JAX-RS with Jersey: Passing form parameters to PUT method for updating a Resource

时光毁灭记忆、已成空白 提交于 2021-02-07 03:35:49

问题


I have to update a Person record having firstName and lastName. User should be able to change it from html form and on submit it should be updated.

Here is my code.

    @PUT
    @Path("/{userId}")
    public Response updatingResource(@FormParam("firstName") String firstName, @FormParam("lastName ") String lastName , @PathParam("userId") String userId){
        System.out.println(firstName);
        System.out.println(lastName);
        return Response.ok().build();
    }

the SOP statements prints null. I have been using Mozilla Firefox's Poster plugin to send PUT request.

I also tried by annotating it with @Consumes(MediaType.APPLICATION_FORM_URLENCODED) but still it is printing null for each values.

How to write and call PUT method that receives these three values. I stumble around lot and found people were asking to use JSON or XML. How can I consume JSON? I would be very greatfull if someone help me to write REST method to update a resource


If I send PUT request using Firefox's RESTClient and Google's rest-client I am able to get the form parameters. Both this tool has something like body section where I placed firstName=Amit&lastName=Patel. Also I added header Content-Type as application/x-www-form-urlencoded.I think Firefox's Poster is buggy. Can anyone suggest me is there any other way I should validate the code or I can trust on first two REST clients?


回答1:


In addition to annotating your method with @Consumes(MediaType.APPLICATION_FORM_URLENCODED), you must send application/x-www-form-urlencodedas a content-type. Did you do it?

Edited: You can use FormParams only with POST:

SRV.4.1.1 When Parameters Are Available The following are the conditions that must be met before post form data will be populated to the parameter set:

  1. The request is an HTTP or HTTPS request.
  2. The HTTP method is POST.
  3. The content type is application/x-www-form-urlencoded.
  4. The servlet has made an initial call of any of the getParameter family of methods on the request object. If the conditions are not met and the post form data is not included in the parameter set, the post data must still be available to the servlet via the request object’s input stream. If the conditions are met, post form data will no longer be available for reading directly from the request object’s input stream.



回答2:


Alternatively you can use an approach as indicated in Overwrite HTTP method with JAX-RS :

You basically would add a hidden parameter / HTTP header and then POST the form. In your servlet, you prepend a Filter that checks for a certain header / hidden form element and changes the POST into PUT request. This is forwarded to your ressource and consumed correctly when annotated with PUT.




回答3:


it is not true that PUT does not accept FormParameters. I use @FormParam with PUT successfully. Maybe it's the @PathParam. I have not tried that.

There seems to be no need for special annotations either. Here is a working class in my application:

package ch.sertal.vision.server.services.objectstore;

import ch.sertal.vision.dao.FormDao;
import ch.sertal.vision.dao.PrepopContentDao;
import ch.sertal.vision.model.Form;
import ch.sertal.vision.model.PrepopContent;
import ch.sertal.vision.model.User;
import ch.sertal.vision.model.exceptions.NotLoggedinException;
import ch.sertal.vision.server.services.AbstractSertalService;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Set;

@Path( "jsonrest/prepop" )
public class PrepopContentStore extends AbstractSertalService {

   @GET
   @Path( "list" )
   @Produces( "application/json" )
   public Response getPrepopEntries( @QueryParam( "formId" ) Long formId ) {
      User user;
      try {
         user = getUser();
      } catch ( NotLoggedinException e ) {
         return Response.status( Response.Status.UNAUTHORIZED ).build();
      }

      PrepopContentDao prepopContentDao = new PrepopContentDao( db );
      List<PrepopContent> contentList = prepopContentDao.list( user, formId );

      JSONArray jsPrepops = new JSONArray();
      for ( PrepopContent content : contentList ) {
         jsPrepops.add( prepopContentDao.getJsContent( content, user ) );
      }

      return Response.ok( jsPrepops.toJSONString(), MediaType.APPLICATION_JSON_TYPE ).build();
   }

   @PUT
   @Produces( "application/json" )
   public Response newPrepopContent( @FormParam( "formId" ) Long formId ) {
      User user;
      try {
         user = getUser();
      } catch ( NotLoggedinException e ) {
         return Response.status( Response.Status.UNAUTHORIZED ).build();
      }

      Form form = (new FormDao( db)).get( formId );

      PrepopContent content = new PrepopContent( form, "" );
      content.setTenant( user.getMainTenant() );
      PrepopContentDao prepopContentDao = new PrepopContentDao( db );
      content = prepopContentDao.save( content );

      return Response.ok( prepopContentDao.getJsContent( content, user ).toJSONString(),
                  MediaType.APPLICATION_JSON_TYPE ).build();
   }

}

It is called from jQuery like so:

    $.ajax( {
       url:"${pageContext.request.contextPath}/services/jsonrest/prepop",
       type:"PUT",
       async:true,
       data: [{name: "formId", value: that.formId}],
       success:function ( prepopContent ) {
          listContainer.append( "<div>" + template( prepopContent ) + "</div>" );
       }
    } );

the ${pageContext.request.contextPath} is from JSP



来源:https://stackoverflow.com/questions/5964122/jax-rs-with-jersey-passing-form-parameters-to-put-method-for-updating-a-resourc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!