Arun
Arun

Reputation: 2572

REST Call with list of headers

I have the following code snippet for invoking rest call. I have around 8 headers to pass on for this rest call. But the problem is that it is difficult to manage. If in case the list of headers are increased in future, I need to change evaluateChange method signature to include the additional headers as method 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);
}

Please provide your thoughts or code snippet to accommodate this.

I tried the following code snippet but it did not work(where headerMap contains all the 8 headers in it):

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

Upvotes: 9

Views: 5651

Answers (5)

Thanga
Thanga

Reputation: 8151

You can send all headers set in a MultivaluedHashMap (javax.ws.rs.core.MultivaluedHashMap) to the Form. this is an acceptable constructor argument for the Form.

    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);

and change your evaluateChange as below,

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

Hope this helps.. Good luck !!

Upvotes: 1

YoYo
YoYo

Reputation: 9415

Not sure why you are trying a Map and not simply a 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
    );
}

Now I did not test this, but this would require all HeaderParams to be called 'HEADER', and they will/should be stored in the List<String> following the order of occurrence.

Upvotes: 0

Arun
Arun

Reputation: 2572

I found a solution using 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);
}

The following is the MyHeader which is a pojo:

public class MyHeader{
@HeaderParam("HEADER1")
    private String header1;

    @HeaderParam("HEADER2")
    private String header2;
.....
// getters and setters present
}

Instantiate MyHeader and set the values to pass it on to the REST service like:

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

and call: evaluateChange(headers, null,request);

PROBLEM: The very big problem with this approach is that everytime there is a new header added we need to make a code change to set and get the values. If the solution is something like passing as a colletion then we don't have that code change involved when new headers are added. like:

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

I am looking for a solution like this. But the above code did not work. Looking for suggestions.

Upvotes: 4

Steffen
Steffen

Reputation: 36

Couldn't you just inject HttpServletRequest and then use its getHeader(String name) method?

API

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

Impl

@Override
public Response evaluateChange(
        @RequestHeader Map<String, String> headerMap,
        @Context HttpServletResponse response, 
        @Context HttpServletRequest httpRequest,
        Request request) {


    String header1 = httpRequest.getHeader("HEADER1");
    ...

Of course, that way you are hiding part of your contract in the implementation.

Upvotes: 2

Robert Br&#228;utigam
Robert Br&#228;utigam

Reputation: 7744

Not exactly sure what you mean, but if you want to get all headers how about this:

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

Found some more code about this here: http://www.mkyong.com/webservices/jax-rs/get-http-header-in-jax-rs/

Edit: How to call the method with a map of key-values.

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...
}

And then just do:

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

Upvotes: 2

Related Questions