0

So I am standing up a rest service. It is going to request a post to a resource that is pretty complex. The actual backend requires multiple (19!) parameters. One of which is a byte array. It sounds like this is going to need to be serialized by the client and sent to my service.

I am trying to understand how I can right a method that will handle this. I am thinking something like this

@POST
@Path("apath")
@Consumes(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML)
public Response randomAPI(@Parameter apiID, WhatParamWouldIPutHere confused){
}

What parameter types would I do to capture that inbound (Serialized) Post data. And what would the client URI look like?

SoftwareSavant
  • 9,467
  • 27
  • 121
  • 195
  • Server/Java - side, a common pattern in Spring is to create your own class that has all the parameters you described, and then the JSON maps to that class when it hits this method. I.e. your `MyClass` would have setters/getters for `String someProperty1`, `int otherQuantity` and the POST data parameters would need to have the same names - `{someProperty1: "hello world", otherQuantity: 45}` – Don Cheadle Jul 15 '16 at 17:21
  • Sounds similar to what I am going to have to do in RESTEasy – SoftwareSavant Jul 15 '16 at 17:36
  • This is a REST end point? That serves the request and responds ?? Make me clear – Tharsan Sivakumar Jul 15 '16 at 17:38
  • This is a REST endpoint. a user will POST to this endpoint with a very complex request including byte[] – SoftwareSavant Jul 15 '16 at 17:40
  • Are the 19 parameters really 19 parameters or are they just fields in your JSON or HTML? Concerning byte as path-, matrix- or query-parameter (or as HTML or JSON content): You need to encode it into something that you can later decode to bytes again, base64 is quite handy therefore. This however requires explicit documentation. A true autonomous HATEOAS capable REST-client (agent) might not be able to send the correct data though without a-priori knowledge! If text and bytes should be mixed on content-level have a look at multipart-content – Roman Vottner Jul 15 '16 at 18:04

2 Answers2

1

In order to get all the parameters of the request you can use @Context UriInfoas parameter of your randomAPI method.

Then use UriInfo#getQueryParameters() to get the full MultivaluedMap of parameters.

if you wish to convert the MultivaluedMap to a simple HashMap I added the code for that too.

so your method will basically look like something like this:

@POST
@Path("apath")
@Consumes(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML)
public Response randomAPI(@Context UriInfo uriInfo){
    Map params= (HashMap) convertMultiToHashMap(uriInfo.getQueryParameters());
    return service.doWork(params);
}

public Map<String, String> convertMultiToHashMap(MultivaluedMap<String, String> m) {
        Map<String, String> map = new HashMap<String, String>();
        for (Map.Entry<String, List<String>> entry : m.entrySet()) {
            StringBuilder sb = new StringBuilder();
            for (String s : entry.getValue()) {
                sb.append(s);
            }
            map.put(entry.getKey(), sb.toString());
        }
        return map;
    }

Additional Info :

The @Context annotation allows you to inject instances of javax.ws.rs.core.HttpHeaders, javax.ws.rs.core.UriInfo, javax.ws.rs.core.Request, javax.servlet.HttpServletRequest, javax.servlet.HttpServletResponse, javax.servlet.ServletConfig, javax.servlet.ServletContext, and javax.ws.rs.core.SecurityContext objects.

Jalal Sordo
  • 1,605
  • 3
  • 41
  • 68
  • So the client app for this will be native mobile clients (Android, Iphone). Couldn't they assemble post form elements and send them to my server? Couldn't I fetch the values that way? How would that look? – SoftwareSavant Jul 17 '16 at 00:47
  • That's definitely a new question and should be asked separately. – Jalal Sordo Jul 17 '16 at 00:48
1

What I am thinking is you can simply use the httpservlet request and all the parameters can be retrieved as below

@RequestMapping(value = "/yourMapping", method = RequestMethod.POST)
public @ResponseBody String yourMethod(HttpServletRequest request) {
          Map<String, String[]> params = request.getParameterMap();
          //Loop through the parameter maps and get all the paramters one by one including byte array
          for(String key : params){
            if(key == "file"){  //This param is byte array/ file data, specially handle it
            byte[] content = params.get(key);
             //Do what ever you want with the byte array

            else if(key == "any of your special params") {
             //handle
            }

            else {
            }

          }
}

http://docs.oracle.com/cd/E17802_01/products/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getParameterMap%28%29

Tharsan Sivakumar
  • 6,351
  • 3
  • 19
  • 28