简体   繁体   English

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

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

I wrote a Web API in Java (JAX-RS by Jersey) which returns "403 Forbidden" with JSON. 我用Java编写了一个Web API(泽西岛的JAX-RS),它使用JSON返回“403 Forbidden”。

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

{"resultCode":"..."}

It works on the local GAE dev server as expected. 它按预期在本地GAE开发服务器上运行。 However, on the real GAE, the content type is changed from JSON to HTML . 但是, 在真正的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>

How can I prevent GAE from changing the content type and the entity body? 如何防止GAE更改内容类型和实体主体?


Additional Information 附加信息

My endpoint does not throw any exception. 我的端点不会抛出任何异常。 It returns a Response instance. 它返回一个Response实例。 The code snippet below is a test endpoint. 下面的代码片段是测试端点。 On the local GAE dev server, this endpoint returns JSON. 在本地GAE dev服务器上,此端点返回JSON。 On the real GAE, it returns HTML. 在真正的GAE上,它返回HTML。 Too much of a good thing. 太好了。

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


Additional Information 2 附加信息2

I wrote a simpler example code like below. 我写了一个更简单的示例代码,如下所示。 This code returns JSON even on the real GAE! 即使在真正的GAE上,此代码也会返回JSON! What's the difference? 有什么不同?

 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\\"}"); } } 

I read Jersey's source code and intuited this answer. 我阅读了泽西岛的源代码并直观地回答了这个问题。

Setting " jersey.config.server.response.setStatusOverSendError " (one of Jersey's server configuration properties ) to true solved the issue. 将“ jersey.config.server.response.setStatusOverSendError ”(Jersey的服务器配置属性之一 )设置为true可解决此问题。

The following is an excerpt from my new web.xml. 以下是我的新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>

You'll have to define your own exception mapper and payload extensions in your service context file: 您必须在服务上下文文件中定义自己的异常映射器和有效负载扩展:

<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 implements ExceptionMapper, ResponseExceptionMapper. my-custom-exception-mapper实现了ExceptionMapper,ResponseExceptionMapper。 Something like this is a good start: http://www.luckyryan.com/2013/06/15/apache-cxf-exception-handler-for-jaxrs-rest/ 这样的事情是一个好的开始: http//www.luckyryan.com/2013/06/15/apache-cxf-exception-handler-for-jaxrs-rest/

Mentioned solution without web.xml may look like: 没有web.xml的解决方案可能如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java - 当响应代码为 4xx 时,如何从 REST API 解析响应正文 - How to parse reponse body from REST API when response code is 4xx in java 如何使用4xx / 5xx状态代码,Java servlet / HttpURLConnection处理HTTP响应 - How to handle HTTP response with a 4xx/5xx status code, Java servlet/HttpURLConnection TestRestTemplate 为 4xx 状态代码抛出异常 - TestRestTemplate throws exception for 4xx status codes MVC-当自定义内容类型时接受JSON(不是application / json) - MVC - Accept JSON when content-type is custom (not application/json) MockMvc 抛出内部异常而不是返回带有 4xx 状态码的响应 - MockMvc throws internal exception instead of returning response with 4xx status code 使用原生 Java 检查 4xx Http 代码 - check for 4xx Http Code with native Java 防止Tomcat在HTTP错误状态4xx或5xx上干扰Jersey / JAX-RS 2响应主体 - Prevent Tomcat from interfering with Jersey/JAX-RS 2 Response Body on HTTP Error Status 4xx or 5xx Spring是否更改Content-Type的标题? - Spring Changes Header for Content-Type? Java 代码中的“内容类型”无效,但在 Postman 中有效 - Invalid "Content-Type" from Java code but works in Postman https状态代码415甚至作为休息请求的一部分指定的内容类型 - https status code 415 even content-type specified as part of Rest-request
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM