【问题标题】:JAX-RS with Jersey: Passing form parameters to PUT method for updating a ResourceJAX-RS with Jersey:将表单参数传递给 PUT 方法以更新资源
【发布时间】:2011-05-11 12:21:48
【问题描述】:

我必须更新具有名字和姓氏的个人记录。用户应该能够从 html 表单更改它并在提交时更新它。

这是我的代码。

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

SOP 语句打印 null。我一直在使用 Mozilla Firefox 的海报插件来发送 PUT 请求。

我也尝试使用 @Consumes(MediaType.APPLICATION_FORM_URLENCODED) 对其进行注释,但它仍然为每个值打印 null。

如何编写和调用接收这三个值的 PUT 方法。我偶然发现了很多人要求使用 JSON 或 XML。如何使用 JSON?如果有人帮助我编写 REST 方法来更新资源,我会非常高兴


如果我使用 Firefox 的 RESTClient 和 Google 的 rest-client 发送 PUT 请求,我可以获取表单参数。这两个工具都有类似于我放置firstName=Amit&lastName=Patel 的正文部分。我还添加了标题Content-Type 为application/x-www-form-urlencoded。我认为Firefox 的Poster 是错误的。任何人都可以建议我是否有其他方法可以验证代码或者我可以信任前两个 REST 客户端?

【问题讨论】:

    标签: java rest jaxb jersey jax-rs


    【解决方案1】:

    除了使用@Consumes(MediaType.APPLICATION_FORM_URLENCODED) 注释您的方法之外,您还必须将application/x-www-form-urlencoded 作为内容类型发送。你做到了吗?

    已编辑:您只能将 FormParams 与 POST 一起使用:

    SRV.4.1.1 参数可用时 在将表单数据填充到之前必须满足的条件 参数集:

    1. 请求是 HTTP 或 HTTPS 请求。
    2. HTTP 方法是 POST。
    3. 内容类型为 application/x-www-form-urlencoded。
    4. servlet 已对请求对象上的任何 getParameter 系列方法进行了初始调用。如果条件不满足 并且post表单数据不包含在参数集中,post servlet 仍然可以通过请求对象的 输入流。如果满足条件,则不再发布表单数据 可直接从请求对象的输入中读取 流。

    【讨论】:

    • 是的,我在发送请求时将内容类型指定为 {application/x-www-form-urlencoded}
    • 哦,没注意你用的是PUT:你必须用带有表单参数的POST。
    • 如果你想改变你应该使用 PUT 的资源。当您要创建资源时使用 POST 方法。在这里,我想更改人员详细信息,因此使用了 PUT。我应该改用 POST 吗?
    • 是的,我知道,但表单参数仅适用于 POST。请参阅编辑后的答案。
    • 如果您在 html 表单字段定义中设置“id”标签而不是“name”标签,您也可能会得到空值。所以 会返回 null 但 会返回正确的结果。
    【解决方案2】:

    或者,您可以使用Overwrite HTTP method with JAX-RS 中指示的方法:

    您基本上会添加一个隐藏参数/HTTP 标头,然后发布表单。在您的 servlet 中,您预先添加一个过滤器来检查某个标题/隐藏的表单元素并将 POST 更改为 PUT 请求。这将转发到您的资源并在使用 PUT 进行注释时正确使用。

    【讨论】:

    • 通过这种方法,我可以登陆 POST 请求,并将标头“X-HTTP-Method-Override”设置为 PUT,但表单参数仍然为空。
    • 嗯,很难说,在你的 servlet 中钩住过滤器之后,它应该已经根据需要更改了请求。你有什么错误吗?
    • 请在下面查看我的答案。我想我是在使用错误的工具来发送 REST PUT 请求
    • 使用上述方法,您应该能够 POST(所有浏览器都可以这样做)并添加标题以便 Jersey 过滤器启动或添加隐藏的表单参数(如果帖子中提到的弹簧过滤器)。所以请求只会在内部 - 在到达服务器之后 - 转换为所需的 PUT 请求。
    【解决方案3】:

    PUT 不接受 FormParameters 是不正确的。我成功地将@FormParam 与 PUT 一起使用。也许是@PathParam。我没试过。

    似乎也不需要特殊注释。这是我的应用程序中的一个工作类:

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

    它是这样从 jQuery 调用的:

        $.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>" );
           }
        } );
    

    ${pageContext.request.contextPath} 来自 JSP

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 1970-01-01
      • 2016-05-05
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      相关资源
      最近更新 更多