簡體   English   中英

無法在REST / JERSEY中調用@DELETE Web服務

[英]Not able to invoke an @DELETE web service in REST/JERSEY

我正在使用Jersey框架(JAX-RS實現)來構建RESTful Web服務。

我無法使用@DELETE REST方法,因為當我嘗試調用它時會拋出異常。以下@DELETE方法用於刪除Employee:

@Path("/employees")
public class EmpResource {

@DELETE
@Consumes(MediaType.APPLICATION_JSON)
public Response deleteEmployee(JAXBElement<String> r) throws ClassNotFoundException, SQLException {

    String name = r.getValue();
    String response = DAOaccess.deleteEmp(name);
    return Response.noContent().build();    

}

我正在使用以下代碼塊來調用服務:

Client client = Client.create();
WebResource webResource = client.resource("http://localhost:8080/RestApp/sample/employees");
String input = "{\"name\":\"John\"}";
ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).delete(ClientResponse.class,input);

當我運行客戶端時,它將引發以下異常:

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: java.net.ProtocolException: HTTP method DELETE doesn't support output
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:151)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.delete(WebResource.java:599)

如果有人可以指導我解決問題,那就太好了嗎?

HTTPUrlConnection類的實現是Java的錯誤:

http://bugs.sun.com/view_bug.do?bug_id=7157360

應該在java 8 .....中解決。

同時,實際上,要將json發送到REST服務,您必須發送路徑參數(如@Micer所說),或進行自己的HttpUrlConnection設置request方法為POST並使用“ X-HTTP_method-Override”覆蓋說您要執行以下刪除操作:

  public static void remove(String dflowname) throws IOException, ParseException {
    String jsonResponse = "";

    URL url = new URL(deleteuri);
    HttpURLConnection connection = null;
    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    // We have to override the post method so we can send data
    connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");
    connection.setDoOutput(true);

    // Send request
    OutputStreamWriter wr = new OutputStreamWriter(
      connection.getOutputStream());
    wr.write(dflowname);
    wr.flush();

    // Get Response
    BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String line;
    while ((line = rd.readLine()) != null) {
      jsonResponse = jsonResponse.concat(line);
    }
    wr.close();
    rd.close();

    JSONParser parser = new JSONParser();
    JSONObject obj = (JSONObject) parser.parse(jsonResponse);
    System.out.println(obj.get("status").toString());
  }

來源: https//groups.google.com/a/openflowhub.org/forum/#!msg / floodlight-dev / imm_8drWOwU / Uu4h_u3H6HcJ

對我來說,它有助於從客戶端的delete()方法中刪除輸入參數

ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).delete(ClientResponse.class);

並通過@pathParam發送:

public String delete(@PathParam("input") String input){...}

帶有有效負載的刪除在Jersey客戶端2.xx中工作正常

下面的客戶端代碼示例。

    public CalculateResult unoverrideSubscription(String partyId, String serviceCode) {


    CalculateResult svc = r.path("/party-subscriptions").path(partyId)
            .path(serviceCode)
            .path("price")
            .request(MediaType.APPLICATION_JSON).delete(CalculateResult.class);

    return svc;// toGenericResponse(sr);
}

這似乎是由於HttpURLConnection類的Java 1.7實現中的錯誤( https://bugs.openjdk.java.net/browse/JDK-7157360 )引起的。 我嘗試使用JDK1.8,它就像一個魅力。

花了一些時間來嘗試確定當前使用WebLogic 12和Sun / JRocket 1.6可以解決的問題以及不能解決的問題。

錯誤“ ProtocolException:HTTP方法DELETE不支持輸出”似乎有點誤導。 該錯誤不是由RS返回輸出而是由嘗試傳遞要在刪除請求中處理的對象引起的。

通過@QueryParams傳遞鍵/標識符時,您可以收到一個對象...

@DELETE
@Path("deleteThis")
public Response deleteThis(@QueryParam("objectId") String objectId)

using

    ClientResponse response = webResource.path("deleteThis").queryParam("objectId", "1").delete(ClientResponse.class);

或通過@PathParams ...

@DELETE
@Path("deleteThis/{objectId}")
public ReturnedObject deleteThis(@PathParam("objectId") int objectId)

using

    ReturnedObject myReturnedObject = webResource.path("deleteThis").path("1").delete(ReturnedObject.class);

當您傳遞要用作參數的對象時,會產生此錯誤

@DELETE
@Path("deleteThis")
public Response deleteRuleSettingTest(ArgumentObject myObject)

using

ArgumentObject myArgumentObject = ...
ClientResponse response = webResource.path("deleteThis").delete(ClientResponse.class, myArgumentObject);

另外。 查看了sun.net.www.protocol.http.HttpURLConnection類的源代碼。 當方法不是PUT或POST時,僅在協議為'http'時,才產生此錯誤。 啟用並將客戶端指向容器上的安全端口,最后一個示例(導致異常的示例)成功運行。 讓我懷疑這是否真的像某些人所建議的那樣是一個Java錯誤。

您必須為所有類型的請求創建一個過濾器

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

如錯誤所示,

HTTP方法DELETE不支持輸出

因此,您必須將方法的簽名更改為

public Response deleteEmployee(...)

在該方法中,不返回String但例如

return Response.noContent().build();

@DELETE方法的返回類型應該為void 你不能退回任何東西。 成功后,響應狀態可以是200或204

我通常像void一樣使用DELETE:

@DELETE
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/")
public void deleteSomeBean(@QueryParam("id") String id) throws Exception

並在客戶中:

webResource.path(SERVICE_PATH).queryParam("id", someBean.getId()).delete();gith

就像這里: TemplateRestService

此處: TemplateServiceRestTest

我確實遇到過Java 1.7的相同問題。它在JDK1.8中有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM