JAX-RS with Jersey:将表单参数传递给 PUT 方法以更新资源

发布于 2024-11-06 15:00:57 字数 1222 浏览 0 评论 0原文

我必须更新具有名字和姓氏的人员记录。用户应该能够从 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 的 Poster 插件来发送 PUT 请求。

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

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


如果我使用 Firefox 的 RESTClient 和 Google 的 rest-client 我是能够获取表单参数。这两个工具都有类似主体部分的内容,我在其中放置了 firstName=Amit&lastName=Patel。另外,我将标头 Content-Type 添加为 application/x-www-form-urlencoded。我认为 Firefox 的 海报 有问题。谁能建议我是否有其他方法可以验证代码或者我可以信任前两个 REST 客户端?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神经大条 2024-11-13 15:00:57

除了使用 @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 使用
    输入流。如果满足条件,则不再发布表单数据
    可直接从请求对象的输入中读取
    流。

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.
寄风 2024-11-13 15:00:57

或者,您可以使用 使用 JAX-RS 覆盖 HTTP 方法中所示的方法

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

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.

香橙ぽ 2024-11-13 15:00:57

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文