【问题标题】:REST Call with list of headers带有标头列表的 REST 调用
【发布时间】:2016-01-25 16:33:48
【问题描述】:

我有以下代码 sn-p 用于调用休息调用。我有大约 8 个标题要传递给这个休息电话。但问题是它很难管理。如果将来增加标头列表,我需要更改evaluateChange 方法签名以将附加标头包含为方法params

@Path("/v1/restclienturi/")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public interface RestClient {

    @POST
    @Path("/samplecall/evaluate")
    Response evaluateChange(
            @HeaderParam("HEADER1") String header1,
            @HeaderParam("HEADER2") String header2,
            @HeaderParam("HEADER3") String header3,
            @HeaderParam("HEADER4") String header4,
            @HeaderParam("HEADER5") String header5,
            @HeaderParam("HEADER6") String header6,
            @HeaderParam("HEADER7") String header7,
            @HeaderParam("HEADER8") String header8,
            @Context HttpServletResponse response, Request request);
}

请提供您的想法或代码 sn-p 以适应这种情况。

我尝试了以下代码 sn-p 但它不起作用(其中 headerMap 包含其中的所有 8 个标头):

@Path("/v1/restclienturi/")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public interface RestClient {

    @POST
    @Path("/samplecall/evaluate")
    Response evaluateChange(
            @RequestHeader Map<String, String> headerMap,
            @Context HttpServletResponse response, Request request);
}

【问题讨论】:

    标签: java rest http-headers client


    【解决方案1】:

    我找到了使用 javax.ws.rs.core.Form 的解决方案:

     @Path("/v1/restclienturi/")
    @Consumes({ MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_JSON })
    public interface RestClient {
    
        @POST
        @Path("/samplecall/evaluate")
        Response evaluateChange(
                @Form MyHeader headers,
                @Context HttpServletResponse response, Request request);
    }
    

    下面是一个pojo的MyHeader:

    public class MyHeader{
    @HeaderParam("HEADER1")
        private String header1;
    
        @HeaderParam("HEADER2")
        private String header2;
    .....
    // getters and setters present
    }
    

    实例化 MyHeader 并设置值以将其传递给 REST 服务,例如:

    MyHeader headers = new MyHeader();
    headers.setHeader1("HEADER1_VALUE");
    ...
    

    并致电:evaluateChange(headers, null,request);

    问题: 这种方法最大的问题是每次添加新的标头时,我们都需要更改代码以设置和获取值。如果解决方案类似于作为集合传递,那么在添加新标头时我们不会涉及代码更改。喜欢:

    Map<String,String> headersMap = new HashMap();
    headers.put("HEADER1","HEADER1_VALUE");
    ....
    evaluateChange(headersMap,null,request);
    

    我正在寻找这样的解决方案。但是上面的代码不起作用。寻找建议。

    【讨论】:

    • 您已经选择了您自己的答案作为正确答案,您还需要帮助吗?无论如何,您似乎都在尝试实现类似工厂的东西。您可以直接实现理论中定义的工厂模式。
    • @Rafa:我找到了解决方案,但仍然存在上述问题。实现工厂或任何其他设计模式都不能解决问题(因为使用工厂模式时 REST 服务不接受标头)。
    • @Arun 我有一个新的解决方案可以根据需要创建多个标题。请查看here
    【解决方案2】:

    不完全确定您的意思,但是如果您想获取所有标题,该怎么办:

    public Response evaluateChange(@Context HttpHeaders headers, ...) {
        String header1 = headers.getRequestHeader("HEADER1").get(0);
        ...
    }
    

    在此处找到更多关于此的代码:http://www.mkyong.com/webservices/jax-rs/get-http-header-in-jax-rs/

    编辑:如何使用键值映射调用方法。

    public class MapHttpHeaders implements HttpHeaders {
       private Map<String, String> values;
    
       public MapHttpHeaders(Map<String, String> values) {
          this.values = values;
       }
    
       @Override
       public String getHeaderString(String key) {
          return values.get(key);
       }
    
       @Override
       public List<String> getRequestHeader(String key) {
          String value = getHeaderString(key);
          if (value == null) {
             return null;
          } else {
             return asList(value);
          }
       }
       ...and so on...
    }
    

    然后就这样做:

    evaluateChange(new MapHttpHeaders(values), ...);
    

    【讨论】:

    • Brautigam:从您的解决方案中,假设我正在尝试调用此 evaluateChange() api。我需要将标头传递给此方法。我在我的代码库中将此标头作为哈希图。你如何将它传递给这个方法(因为这个方法只需要 HttpHeaders)。请提供示例代码。
    • 你只需要实现 HttpHeaders 接口就可以在 Map 中工作,见上面我的编辑。大多数方法不需要做任何事情,最重要的方法如上所示。
    • 我尝试了上面的实现,我仍然无法传递标题。我也尝试覆盖所有方法。还是没用。任何指针或想法如何在服务器端读取此 HttpHeaders...
    • 服务器端会自动传给你参数。如果您的端点已部署,它应该可以工作。上面的实现仅用于测试。
    • 我还尝试了以下代码 sn-p 而不是 @Context: public Response evaluateChange(@RequestHeader Map headerMap, ...) { String header1 = headers.getRequestHeader("HEADER1 ").get(0); ... } 仍然没有用。
    【解决方案3】:

    你不能只注入 HttpServletRequest 然后使用它的 getHeader(String name) 方法吗?

    API

    @POST
    @Path("/samplecall/evaluate")
    Response evaluateChange(
            @RequestHeader Map<String, String> headerMap,
            @Context HttpServletResponse response, 
            @Context HttpServletRequest httpRequest,
            Request request);
    

    实施

    @Override
    public Response evaluateChange(
            @RequestHeader Map<String, String> headerMap,
            @Context HttpServletResponse response, 
            @Context HttpServletRequest httpRequest,
            Request request) {
    
    
        String header1 = httpRequest.getHeader("HEADER1");
        ...
    

    当然,这样你在实现中隐藏了部分合同。

    【讨论】:

    • 我是客户不是服务...需要形成并传递这个HttpServletRequest
    【解决方案4】:

    您可以将 MultivaluedHashMap (javax.ws.rs.core.MultivaluedHashMap) 中设置的所有标头发送到表单。这是表单可接受的构造函数参数。

        MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<String, String>();
        headersMap.putSingle("HEADER1","HEADER1_VALUE");
        headersMap.putSingle("HEADER2","HEADER1_VALUE");
        .
        .
        .
        headersMap.putSingle("HEADER8","HEADER8_VALUE");
    
        evaluateChange(headersMap,null,request);
    

    并如下更改您的evaluateChange

    Response evaluateChange(
            @Form MultivaluedMap headers,
            @Context HttpServletResponse response, Request request);
    

    希望这会有所帮助.. 祝你好运!!

    【讨论】:

      【解决方案5】:

      不确定您为什么要尝试Map 而不仅仅是List

      @Path("/v1/restclienturi/")
      @Consumes({ MediaType.APPLICATION_JSON })
      @Produces({ MediaType.APPLICATION_JSON })
      public interface RestClient {
      
          @POST
          @Path("/samplecall/evaluate")
          Response evaluateChange(
                  @HeaderParam("HEADER") List<String> headers,
                  @Context HttpServletResponse response, Request request
          );
      }
      

      现在我没有对此进行测试,但这需要将所有 HeaderParams 称为“HEADER”,并且它们将/应该按照出现的顺序存储在 List&lt;String&gt; 中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-09
        • 2018-12-07
        • 2019-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-12
        相关资源
        最近更新 更多