等价于 POST 和从 HttpServlet 到 REST 的 GET

Equivalent POST and GET from HttpServlet to REST

我正在尝试了解将 HttpServlet 模仿为 Restful 网络服务的等效方法。


我有以下 HttpServlet 代码:

public class Servlet extends HttpServlet {

   public void doPost(HttpServletRequest req, HttpServletResponse res) {
      String reqXml = req.getParameter("xmlrequest");
   }

   public void doGet(HttpServletRequest req, HttpServletResponse res) {
      String reqXml = req.getParameter("xmlrequest");
   }

}

我正尝试在 REST 中采用相同的方式。

这是我的代码:

@GET
@Path("/getInfo")
@Produces(MediaType.APPLICATION_XML)
public Response getDetails(@Context HttpServletRequest request) {
    String xmlRequest = request.getParameter("xmlrequest");
}



@GET
@Path("/getInfo")
@Produces(MediaType.APPLICATION_XML)
public Response getDetails(@FormParam("xmlrequest") String request) {
    String xmlRequest = request.getParameter("xmlrequest");
}

在做POST请求时,通常参数会作为请求体的一部分作为application/x-www-form-urlencoded数据

POST /api/endpoint HTTP/1.1
Content-Type: application/x-www-form-urlencoded

key1=value1&key2=value2

在服务器上,您将使用 @POST 注释来表示端点用于 POST 请求。要获取参数值,您可以使用 @FormParam。有了上面的请求,你会做

@POST
@Comsumes("application/x-www-form-urlencoded")
@Produces("application/xml")
public Response post(@FormParam("key1") String key1, @FormParam("key2") String key1) {}

对于 GET 请求,参数将作为 URL 的一部分以 query string

的形式出现
GET /api/endpoint?key1=value1&key2=value2 HTTP/1.1

在服务器上,您将使用 @GET 来表示端点用于 GET 请求。您将获得带有 @QueryParam 注释

的参数值
@GET
@Produces("application/xml")
public Response get(@QueryParam("key1") String key1, @QueryParam("key2") String key1) {}

何时使用查询参数和表单参数取决于具体情况。通常,当您尝试将 submit/send 数据发送到服务器时,您会使用表单参数。例如,您想保存有关新用户的信息。您将发送一个 POST 请求,其中包含作为表单参数发送的数据。当您尝试从服务器 检索 信息时,您通常会使用查询参数,并将查询参数服务器作为某种过滤机制。例如,您想要获取用户列表并且只想获取前 10 个用户。您可以使用 URL /api/users?limit=10[中的 limit=10 参数向用户端点发出 GET 请求。 =39=]


如果你想发送XML数据,你不想使用表单参数。您在代码中显示的内容就好像您试图在表单参数内发送 XML 数据,例如

POST /api/endpoint HTTP/1.1
Content-Type: application/x-www-form-urlencoded

xmlrequest=<user>Paul</user>

当你

public void doPost(HttpServletRequest req, HttpServletResponse res) {
   String reqXml = req.getParameter("xmlrequest");
}

那么 reqXml 的值将是 XML 字符串 <user>Paul</user>。这很奇怪,不是你应该做的。 XML应该作为主要请求体发送,Content-Type应该是application/xml.

POST /api/endpoint HTTP/1.1
Content-Type: application/xml

<user>Paul</user>

要获取 servlet 中的数据,您需要读取输入流。您无法通过 getParameter()

获取数据
public void doPost(HttpServletRequest req, HttpServletResponse res) {
    InputStream xmlStream = req.getInputStream();
    String xml = readStream(xmlStream);
}

在 JAX-RS 端点中,您只需使用一个字符串参数

即可获得整个 XML 字符串
@POST
@Consumes("application/xml")
@Produces("application/xml")
public Response post(String xmlString) {}

对于最后一个请求,xmlString 的值将是 <user>Paul</user>

在 JAX-RS 中使用 XML 时,通常会使用 POJOs。假设你有这个 XML

<User>
  <firstName>Jane</firstName>
  <lastName>Doe</lastName>
</User>

我们要做的是将其映射到 POJO,将不同的 XML 元素和属性映射到 POJO 属性。例如,上面的 Xml,我们将它映射到下面的 POJO

@XmlRootElement
public class User {
    private String firstName;
    private String lastName;

    public String getFirstName() { return firstName; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public String getLasttName() { return lastName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
}

现在在我们的资源方法中,我们可以只接受一个 User 作为参数

@POST
@Consumes("application/xml")
@Produces("application/xml")
public Response post(User user) {
    return user;
}