为什么我在进行POST请求时会收到405方法不允许的错误?

4

我对REST服务还比较陌生。我正在尝试创建一个接受客户端JSON字符串的服务。当我使用JQuery调用此服务时,出现了405错误。以下是WS的Java代码:

这是我向JERSEY POST RESTful Web服务发送请求的方式。

var orderinfo = {'ordersplitjson': ordersplitjson, 'customer_id': cust_id , 'homedelivery': homedelivery, 'seatnum' :seatnum , 'locationname':location_nam , 'rownum':rownum}; 
var json_data =  JSON.stringify(orderinfo);
        var ajaxcallquery = $.ajax({
            type:'POST',
              dataType: 'jsonp',
             data: json_data,
             contentType: "application/json; charset=utf-8",
            url:url+'/OMS/oms1/orderinsertservice',
            jsonpCallback:'jsonCallback',
            jsonp:false,
            success: function(response) 
            {
            },
            error: function(jqxhr, status, errorMsg) {
            alert('Failed! ' + errorMsg);
        }

        });


 public class OrdersInsertService 
{
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces("application/json")
    public String getData(OrderInfo order,@Context HttpServletResponse serverResponse)
    throws JSONException
            {
         serverResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
            serverResponse.addHeader("Access-Control-Allow-Credentials", "true");
            serverResponse.addHeader("Access-Control-Allow-Origin", "*");
           serverResponse.addHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
            serverResponse.addHeader("Access-Control-Max-Age", "60");

}
}


package com.util;

public class OrderInfo {

    String ordersplitjson;
    public String getOrdersplitjson() {
        return ordersplitjson;
    }
    public void setOrdersplitjson(String ordersplitjson) {
        this.ordersplitjson = ordersplitjson;
    }
    public String getCustomer_id() {
        return customer_id;
    }
    public void setCustomer_id(String customer_id) {
        this.customer_id = customer_id;
    }
    public String getHomedelivery() {
        return homedelivery;
    }
    public void setHomedelivery(String homedelivery) {
        this.homedelivery = homedelivery;
    }
    public String getSeatnum() {
        return seatnum;
    }
    public void setSeatnum(String seatnum) {
        this.seatnum = seatnum;
    }
    public String getLocationname() {
        return locationname;
    }
    public void setLocationname(String locationname) {
        this.locationname = locationname;
    }
    public String getRownum() {
        return rownum;
    }
    public void setRownum(String rownum) {
        this.rownum = rownum;
    }
    String customer_id;

    String homedelivery;
    String seatnum;

    String locationname;
    String rownum;


}

请问有谁能告诉我如何解决这个问题

在此输入图片描述

我正在使用Jersey 1,在使用您的类时,在eclipse中它显示编译错误,如下图所示:

在此输入图片描述


摆脱所有与jsonp相关的内容。jsonp将自动转换为GET(因此是405)。使用POST的jsonp不好。 - Paul Samsotha
当我将jsonp修改为json时,请求的资源上没有'Access-Control-Allow-Origin'头。因此,来自'null'的访问是不允许的。 - Pawan
我已经按照你的建议编写了一个新类,但是我遇到了问题:The method filter(ContainerRequest, ContainerResponse) of type CORSFilter must override a superclass method - implements com.sun.jersey.spi.container.ContainerResponseFilter.filter。 - Pawan
如果您使用Jersey 1,请使用原始帖子中的类,而不是答案。答案代码正在使用Jersey 2。 - Paul Samsotha
我会回答的,请稍等一下。 - Paul Samsotha
显示剩余7条评论
1个回答

3
(1) dataType: 'jsonp' 应该改为 json。删除所有与 jsonp 相关的内容。应该使用 json。jsonp 会自动转换为 GET 请求,因此会出现 405(方法不允许)错误。你的资源方法接受 POST 请求。
(2) CORS 问题。你需要一个过滤器来处理预检请求。如果你正在使用 Jersey 1,你可以使用这个类。
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;

public class CORSFilter implements ContainerResponseFilter {
    @Override
    public ContainerResponse filter(ContainerRequest request,
            ContainerResponse response) {

        response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHttpHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHttpHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");

        return response;
    }
}

然后像这样注册它:
resourceConfig.getContainerResponseFilters().add(new CORSFilter());

使用web.xml,添加以下内容:
<init-param>
  <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
  <param-value>com.yourpackage.CORSFilter</param-value>
</init-param>

在包含Jersey servlet的<servlet>元素内部。

嗨,我正在使用Jersey 1,当我使用你的类时,在eclipse中出现编译错误,如我问题中所示的图片,你能告诉我如何摆脱这个错误吗? - Pawan
抱歉,它给了我 - implements com.sun.jersey.spi.container.ContainerResponseFilter.filter
  • 类型CORSFilter的方法filter(ContainerRequest, ContainerResponse)必须覆盖超类方法。
- Pawan
我不知道我没有问题。我从我的IDE复制粘贴了上面的代码。 - Paul Samsotha
抱歉,我之前使用的是JDK 1.5,现在改用了JDK 1.6,错误已经消失了。现在我该如何在我的OrderInsertService类中访问resourceConfig.getContainerResponseFilters().add(new CORSFilter())呢? - Pawan
你是使用 web.xml 还是 ResourceConfig 类来进行应用程序开发? - Paul Samsotha
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接