Question

Altough I'm sure to certainly not be the first to wonder about this, I haven't found similiar topics with my specific issue. I'm trying to post data to my RESTful service in Java:

@POST
@Path("{projectId}/rename")
@Produces(MediaType.APPLICATION_JSON)
public Response renameProject(@PathParam("projectId") final Long projectId, String name) {
    Logger.getLogger(ProjectService.class.getName()).info("rename project service called " + name);
    return requestHandler.handleRenameProject(projectId, name);
}

I'm using this JS function to do it

function renameProject(projectId, name) {
    $.post('/rest/projects/' + projectId + '/rename', {name : name}, function(data) {
        /* change project name in sidebar */
        $("a[data-pk='" + data.key.id + "']").text(name);
    }, 'json');
}

Now to my surprise the output of the log is

  [INFO] Apr 28, 2014 6:56:05 PM de.uniluebeck.collaboratex.service.ProjectService renameProject
  [INFO] Information: rename project service called name=New+Project

How come the parameter does contain not only the value but also it's own name as concatenated String? I guess I must not be sending things as JSON? Which is also hinting me in that direction is the fact, that the service in Java used to be annotated with

  @Consumes(MediaType.APPLICATION_JSON)

as well but that lead to 415 Unsupported Media Type errors. Glad for any input, guess this must be an easy one. :)

Was it helpful?

Solution

Your parameter name isn't annotated as a @*Param, so it'll get the full message body, which in your case is of type application/x-www-form-urlencoded as jQuery.ajax() explains:

The data option can contain either a query string of the form key1=value1&key2=value2, or an object of the form {key1: 'value1', key2: 'value2'}. If the latter form is used, the data is converted into a query string using jQuery.param() before it is sent. This processing can be circumvented by setting processData to false. The processing might be undesirable if you wish to send an XML object to the server; in this case, change the contentType option from application/x-www-form-urlencoded to a more appropriate MIME type.

So you have two options:

Option 1: Use @FormParam like so:

@POST
@Path("{projectId}/rename")
@Produces(MediaType.APPLICATION_JSON)
public Response renameProject(@PathParam("projectId") Long projectId, 
                              @FormParam("name") String name) {
    return Reponse.ok().build();
}

Option 2: Send proper json like so:

@POST
@Path("{projectId}/rename")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response renameProject(@PathParam("projectId") Long projectId, 
                              Map<String, String> paramMap) {
    return Reponse.ok().build();
}

And in your JS:

$.ajax({
  url: '/rest/projects/' + projectId + '/rename', 
  data: JSON.stringify({name : name}),
  processData: false,
  contentType: 'application/json',
  dataType: 'json',
  success: function(data) {
    console.log(data);
  }
});

You typically only use option 2 with complex datatypes you (de-)serialize with jackson (ie, your client-side object is represented by some entity you can now name as a simple parameter to your Java method).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top