状态码为4xx时,GAE / J将Content-Type从JSON更改为HTML [英] GAE/J changes Content-Type from JSON to HTML when the status code is 4xx

查看:139
本文介绍了状态码为4xx时,GAE / J将Content-Type从JSON更改为HTML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Java编写了一个Web API(Jersey的JAX-RS),它返回了带有JSON的403 Forbidden。

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

{resultCode:...}

它可以像预期的那样在本地GAE dev服务器上运行。然而,在真正的GAE上,内容类型从JSON更改为HTML

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

< html>< head>
< meta http-equiv =content-typecontent =text / html; charset = utf-8>
< title> 403 Forbidden< / title>
< / head>
< body text =#000000 bgcolor =#ffffff>
< h1>错误:禁止< / h1>
< / body>< / html>

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




其他信息



我的端点不会引发任何异常。它返回一个Response实例。下面的代码片段是一个测试端点。在本地GAE开发服务器上,此端点返回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()
{
返回响应
.status(Status.BAD_REQUEST)
.type(MediaType.APPLICATION_JSON_TYPE)
.entity({\id \:1})
.build();






其他信息2



我写了一个更简单的示例代码,如下所示。 即使在真正的GAE上,此代码也会返回JSON!有什么区别?
$ b

  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;
$ b public class TestServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest请求,HttpServletResponse响应)
抛出ServletException,IOException异常
{
response.setStatus(400);
response.setContentType(application / json; charset = UTF-8);
PrintWriter out = response.getWriter();
out.write({\hello \:\world \});
}
}


解决方案

I阅读泽西岛的源代码并直观地回答了这个问题。



设置 jersey.config.server.response.setStatusOverSendError (Jersey's 服务器配置属性)真正解决了这个问题。



以下是我的新web.xml的摘录。
$ b

< 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< /参数值>
< / init-param>
< / servlet>


I wrote a Web API in Java (JAX-RS by Jersey) which returns "403 Forbidden" with JSON.

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

{"resultCode":"..."}

It works on the local GAE dev server as expected. However, on the real GAE, the content type is changed 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 GAE from changing the content type and the entity body?


Additional Information

My endpoint does not throw any exception. It returns a Response instance. The code snippet below is a test endpoint. On the local GAE dev server, this endpoint returns JSON. On the real GAE, it returns 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

I wrote a simpler example code like below. This code returns JSON even on the real GAE! 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.

The following is an excerpt from 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>

这篇关于状态码为4xx时,GAE / J将Content-Type从JSON更改为HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆