簡體   English   中英

當狀態代碼為4xx時,GAE / J將Content-Type從JSON更改為HTML

[英]GAE/J changes Content-Type from JSON to HTML when the status code is 4xx

我用Java編寫了一個Web API(澤西島的JAX-RS),它使用JSON返回“403 Forbidden”。

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=UTF-8
...

{"resultCode":"..."}

它按預期在本地GAE開發服務器上運行。 但是, 在真正的GAE上,內容類型從JSON更改為HTML

HTTP/1.1. 403 Forbidden
Content-Type: text/html; charset=utf-8
...

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
</body></html>

如何防止GAE更改內容類型和實體主體?


附加信息

我的端點不會拋出任何異常。 它返回一個Response實例。 下面的代碼片段是測試端點。 在本地GAE dev服務器上,此端點返回JSON。 在真正的GAE上,它返回HTML。 太好了。

 import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @Path("/test") public class TestEndpoint { @GET public Response get() { return Response .status(Status.BAD_REQUEST) .type(MediaType.APPLICATION_JSON_TYPE) .entity("{\\"id\\":1}") .build(); } } 


附加信息2

我寫了一個更簡單的示例代碼,如下所示。 即使在真正的GAE上,此代碼也會返回JSON! 有什么不同?

 import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setStatus(400); response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); out.write("{\\"hello\\":\\"world\\"}"); } } 

我閱讀了澤西島的源代碼並直觀地回答了這個問題。

將“ jersey.config.server.response.setStatusOverSendError ”(Jersey的服務器配置屬性之一 )設置為true可解決此問題。

以下是我的新web.xml的摘錄。

<servlet>
  <servlet-name>API</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
      ......
    </param-value>
  </init-param>
  <init-param>
    <param-name>jersey.config.server.response.setStatusOverSendError</param-name>
    <param-value>true</param-value>
  </init-param>
</servlet>

您必須在服務上下文文件中定義自己的異常映射器和有效負載擴展:

<jaxrs:server id="my-resources" address="/some-context-path">
    <jaxrs:serviceBeans>
        <ref bean="my-resource-1" />
        <ref bean="my-resource-2" />
    </jaxrs:serviceBeans>
    <jaxrs:extensionMappings>
        <entry key="json" value="application/json"/>
        <entry key="xml" value="application/xml"/>
    </jaxrs:extensionMappings>
    <jaxrs:providers>
        <ref bean="jaxbProvider" />
        <ref bean="my-custom-exception-mapper" />
    </jaxrs:providers>
    <jaxrs:features>
        <cxf:logging/>
    </jaxrs:features>
</jaxrs:server>

my-custom-exception-mapper實現了ExceptionMapper,ResponseExceptionMapper。 這樣的事情是一個好的開始: http//www.luckyryan.com/2013/06/15/apache-cxf-exception-handler-for-jaxrs-rest/

沒有web.xml的解決方案可能如下所示:

new ResourceConfig()
       .property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, true);

暫無
暫無

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

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