Java 如何在Json响应中设置http头

Java 如何在Json响应中设置http头,java,jsonp,cxf,Java,Jsonp,Cxf,我有一个CXF RESTful服务,它返回XML和Json格式。我需要在RESTful服务中添加一个自定义http头。下面是一个示例代码片段 @GET @Path("/test") @Produces("application/xml") public Response test( @QueryParam("p") String var { TestRequest req = new TestRequest();

我有一个CXF RESTful服务,它返回XML和Json格式。我需要在RESTful服务中添加一个自定义http头。下面是一个示例代码片段


    @GET
    @Path("/test")
    @Produces("application/xml")
    public Response test(
            @QueryParam("p") String var
    {
        TestRequest req = new TestRequest();
        req.setVar(var);
        TestResponse res = p.getData(req);
        return Response.ok(res).header("Result", res.getResult()).build();
    }

    @GET
    @Path("/test/jsonp")
    public String testJSONP(
            @QueryParam("p") String var,
            @QueryParam("cb") String callBack
    {
        Response resp = test(var);
        XStream xs = new XStream(new JsonHierarchicalStreamDriver());
        xs.setMode(XStream.NO_REFERENCES);
        xs.alias("TestResponse", TestResponse.class);
        StringBuilder sb = new StringBuilder();
        sb.append(callBack);
        sb.append("(");
        GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalenderSerializer());
        gb.setPrettyPrinting();
        Gson gson = gb.create();
        sb.append(gson.toJson(resp));
        sb.append(")");
        return sb.toString();
    }
上面的代码显示了设置自定义http头“Result”的XML响应。我可以在响应头中看到新的http头。到目前为止还不错

现在,这里是Json版本,它在内部调用testService()方法来获取结果,然后使用google Gson API将结果发送回。这一直运作良好,直到我决定返回新的标题。下面是代码片段


    @GET
    @Path("/test")
    @Produces("application/xml")
    public Response test(
            @QueryParam("p") String var
    {
        TestRequest req = new TestRequest();
        req.setVar(var);
        TestResponse res = p.getData(req);
        return Response.ok(res).header("Result", res.getResult()).build();
    }

    @GET
    @Path("/test/jsonp")
    public String testJSONP(
            @QueryParam("p") String var,
            @QueryParam("cb") String callBack
    {
        Response resp = test(var);
        XStream xs = new XStream(new JsonHierarchicalStreamDriver());
        xs.setMode(XStream.NO_REFERENCES);
        xs.alias("TestResponse", TestResponse.class);
        StringBuilder sb = new StringBuilder();
        sb.append(callBack);
        sb.append("(");
        GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalenderSerializer());
        gb.setPrettyPrinting();
        Gson gson = gb.create();
        sb.append(gson.toJson(resp));
        sb.append(")");
        return sb.toString();
    }
我无法在Json响应中看到http头

如有任何反馈,我们将不胜感激

-谢谢

更新 我在Json方法中添加了以下代码用于测试


    @GET
    @Path("/test/jsonp")
    public String testJSONP(
            @QueryParam("p") String var,
            @QueryParam("cb") String callBack
    {
        Response resp = test(var);
        XStream xs = new XStream(new JsonHierarchicalStreamDriver());
        xs.setMode(XStream.NO_REFERENCES);
        xs.alias("TestResponse", TestResponse.class);
        StringBuilder sb = new StringBuilder();
        sb.append(callBack);
        sb.append("(");
        GsonBuilder gb = new GsonBuilder();
        gb.registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalenderSerializer());
        gb.setPrettyPrinting();
        Gson gson = gb.create();
        sb.append(gson.toJson(resp));
        sb.append(")");
        return Response.ok(sb.toString(), MediaType.APPLICATION_JSON).header("Result", "50").build();
    }
这将正确设置头值,但问题是Json响应格式似乎已更改。由于这是一项现有服务,我不允许这样做。 以下是现有的响应格式


null({
  "status": "Completed",
  "totalResult": "252",
  "bin": [
    {
      "type": "source",
      "value": "documentation",
      "ndocs": "243"
    },
    {
      "type": "source",
      "value": "wikihelp",
      "ndocs": "6"
    },    
  "entries": {
    "item": [
      {
        "url": "http://test.com/test.htm",
        "title": "\u003cspan class\u003d\"vivbold qt0\"\u003eXREF\u003c/span\u003e",
        "snippet": "     Test data.",
        "source": "documentation",
        "type": "html",
        "shortDescription": "Starts the TEST command.",
        "category": [
          "User"
        ],
        "publishDate": "2012-02-05T12:00:00-0500",
        "lastUpdateDate": "2012-03-14T12:00:00-0400",
        "topicId": "GUID-7DD70C3C-B8AD-40F1-8A69-5D1EECEAB013"
      }
    ]
  }
})
下面是添加此更改后的响应


null({
  "status": 200,
  "entity": {
    "status": "Completed",
    "totalResult": "252",
    "bin": [
      {
        "type": "source",
        "value": "documentation",
        "ndocs": "243"
      },
      {
        "type": "source",
        "value": "wikihelp",
        "ndocs": "6"
      }
    ],
    "entries": {
      "item": [
        {
          "url": "http://test.com/test.htm",
          "title": "\u003cspan class\u003d\"vivbold qt0\"\u003eXREF\u003c/span\u003e",
          "snippet": " Test data.",
          "source": "documentation",
          "type": "html",
          "shortDescription": "Starts the TEST command.",
          "category": [
            "User"
          ],
          "publishDate": "2012-02-05T12:00:00-0800",
          "lastUpdateDate": "2012-03-14T12:00:00-0700",
          "topicId": "GUID-7DD70C3C-B8AD-40F1-8A69-5D1EECEAB013"
        }
      ]
    }
  },
  "metadata": {
    "Result": {

    }
  }
})

您需要更改方法的签名,以返回的实例,而不是字符串,然后手动生成响应

从:

更新 您还可以使用如下注释将
HttpServletResponse
注入处理程序:

@Path("/example")
public class Welcome {

    @GET
    public String getSomething(
            @QueryParam("p1") String param1, 
            @QueryParam("p2") String param2, 
            @Context HttpServletResponse response) {

        response.addHeader("CustomHeader", "CustomValue");

        return "my awesome response";
    }
}

请注意,有一个原因导致未注入
HttpServletResponse
,因此您需要一个更新的CXF版本。

@npe..感谢您的响应….我确实在Jsonp方法中使用了以下代码尝试了这一点。。。。返回Response.ok(sb.toString(),MediaType.APPLICATION_JSON).header(“Result”,“200”).build();这会在不更改签名的情况下设置标头,但由于某些原因,这会更改响应格式。由于这是一项现有服务,我不允许这样做。我已经用另一个解决方案更新了答案,请检查。@npe…非常感谢,我不知道HTTPResponse对象可以作为上下文传递。它工作得很好。+1作为参数的
HttpServletResponse
似乎不适用于CXF 2.7版。它抛出“2个IllegalAnnotationExceptions计数”。然而,它确实可以作为一个字段工作。这个答案仍然有效吗尤其是
updateCustomer
方法定义-声明示例仍然有效。也许这是2.7中的一个bug?