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

I wrote a Java web API (JAX-RS from Jersey) that returns "403 Forbidden" with JSON.

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

It runs on a local GAE server, as expected. However, in real GAE, the content type changes from JSON to 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 the GAE from changing the content type and body of the object?

<h / "> Additional information

My endpoint does not raise any exceptions. It returns an instance of Response. Below is a snippet of code - the endpoint of the test. On the local GAE dev server, this endpoint returns JSON. In real GAE, it returns HTML. Too much good.

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

<h> " Additional information 2

I wrote a simpler code example as shown below. This code returns JSON even in real GAE! Who cares?

 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\"}"); } } 
+6
source share
3 answers

I read the source code for Jersey and intuitively understood this answer.

Setting " jersey.config.server.response.setStatusOverSendError " (one of the server configuration properties) to solve this problem.

Below is a snippet of my new 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> 
+6
source

In your service context file, you will need to define your own display and payload extension configurators:

 <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. Something like this is a good start: http://www.luckyryan.com/2013/06/15/apache-cxf-exception-handler-for-jaxrs-rest/

0
source

The mentioned solution without web.xml might look like this:

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

Source: https://habr.com/ru/post/975368/


All Articles