3

我有一个返回 XML 和 Json 格式的 CXF RESTful 服务。我需要在 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 标头“结果”的 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 标头。

任何反馈将不胜感激。

-谢谢

更新

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

    }
  }
})
4

1 回答 1

3

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

CXF 维基页面

@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错误2.1导致HttpServletResponse无法注入,因此您需要更新的 CXF 版本。

于 2012-06-17T19:23:00.437 回答