当状态代码为4xx时,GAE / J将Content-Type从JSON更改为HTML

我用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 ...   403 Forbidden   

Error: Forbidden

如何防止GAE更改内容类型和实体主体?


附加信息

我的端点不会抛出任何exception。 它返回一个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的摘录。

  API org.glassfish.jersey.servlet.ServletContainer  jersey.config.server.provider.classnames  ......    jersey.config.server.response.setStatusOverSendError true   

您必须在服务上下文文件中定义自己的exception映射器和有效负载扩展:

                  

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);