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

时间:2012-06-17 18:32:32

标签: 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();
        req.setVar(var);
        TestResponse res = p.getData(req);
        return Response.ok(res).header("Result", res.getResult()).build();
    }

上面的代码显示了设置自定义http标头“Result”的XML响应。我能够在响应头中看到新的http标头。到目前为止一切都很好。

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


    @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标头。

任何反馈都将受到高度赞赏。

-Thanks

更新

我在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": {

    }
  }
})

1 个答案:

答案 0 :(得分:3)

您需要更改方法的签名,返回Response class的实例,而不是String,然后手动构建响应。

来自CXF wiki page

@Path("/example")
public ExampleResource {
    @GET
    public Response getSomething() {
        return Response.ok(/* some entity */).header("CustomHeader", "CustomValue").build();
    }
}

更新

您还可以使用HttpServletResponse注释将@Context注入您的处理程序,如下所示:

@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";
    }
}

请注意,有CXF-1498 bug in versions prior to 2.1导致HttpServletResponse未被注入,因此您需要更新的CXF版本。