Cách truy cập các tham số trong phương thức RESTful POST


123

Phương thức POST của tôi trông như thế này:

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String param1, String param2){
    System.out.println("param1 = " + param1);
    System.out.println("param2 = " + param2);
}

Khi tôi tạo một Máy khách Jersey trong Netbeans, phương thức gọi phương thức đăng này trông như thế này:

public void create(Object requestEntity){
    webResource.path("create").type(MediaType.APPLICATION_JSON).post(requestEntity);
}

Khi chạy thử nghiệm này:

@Test
public void hello(){
    String json = "{param1=\"hello\",param2=\"hello2\"}";
    this.client.create(json);
}

Nó cung cấp đầu ra sau trong máy chủ:

INFO: param1 = {param1="hello",param2="hello2"}
INFO: param2 = 

Tôi cần thay đổi gì để các tham số đưa ra giá trị chính xác?


Bạn có đang sử dụng ứng dụng này trên ứng dụng Android hay không?
Android-Droid

Cuối cùng tôi muốn gọi phương thức bài này trong một ứng dụng Android. Bằng cách nào đó, dịch vụ web không biết cách ký các giá trị cho các tham số. Tôi muốn biết làm thế nào để làm điều này.
Klaasvaak

Câu trả lời:


355

@POSTPhương thức của bạn nên chấp nhận một đối tượng JSON thay vì một chuỗi. Jersey sử dụng JAXB để hỗ trợ các đối tượng JSON sắp xếp và sắp xếp lại (xem tài liệu về áo để biết chi tiết ). Tạo một lớp như:

@XmlRootElement
public class MyJaxBean {
    @XmlElement public String param1;
    @XmlElement public String param2;
}

Sau đó, @POSTphương pháp của bạn sẽ trông như sau:

@POST @Consumes("application/json")
@Path("/create")
public void create(final MyJaxBean input) {
    System.out.println("param1 = " + input.param1);
    System.out.println("param2 = " + input.param2);
}

Phương thức này hy vọng sẽ nhận được đối tượng JSON làm phần thân của HTTP POST. JAX-RS chuyển nội dung nội dung của thông điệp HTTP dưới dạng tham số không được giám sát - inputtrong trường hợp này. Thông điệp thực tế sẽ trông giống như:

POST /create HTTP/1.1
Content-Type: application/json
Content-Length: 35
Host: www.example.com

{"param1":"hello","param2":"world"}

Sử dụng JSON theo cách này khá phổ biến vì những lý do rõ ràng. Tuy nhiên, nếu bạn đang tạo hoặc tiêu thụ nó trong một thứ khác ngoài JavaScript, thì bạn phải cẩn thận để thoát dữ liệu đúng cách. Trong JAX-RS, bạn sẽ sử dụng MessageBodyReaderMessageBodyWriter để thực hiện điều này. Tôi tin rằng Jersey đã có các triển khai cho các loại bắt buộc (ví dụ: các lớp nguyên thủy Java và các lớp được bọc JAXB) cũng như cho JSON. JAX-RS hỗ trợ một số phương thức khác để truyền dữ liệu. Chúng không yêu cầu tạo một lớp mới vì dữ liệu được truyền bằng cách sử dụng đối số đơn giản.


HTML <FORM>

Các tham số sẽ được chú thích bằng @FormParam :

@POST
@Path("/create")
public void create(@FormParam("param1") String param1,
                   @FormParam("param2") String param2) {
    ...
}

Trình duyệt sẽ mã hóa biểu mẫu bằng cách sử dụng "application / x-www-form-urlencoding" . Thời gian chạy JAX-RS sẽ đảm nhiệm việc giải mã cơ thể và chuyển nó sang phương thức. Đây là những gì bạn nên thấy trên dây:

POST /create HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 25

param1=hello&param2=world

Nội dung là URL được mã hóa trong trường hợp này.

Nếu bạn không biết tên của FormParam, bạn có thể làm như sau:

@POST @Consumes("application/x-www-form-urlencoded")
@Path("/create")
public void create(final MultivaluedMap<String, String> formParams) {
    ...
}

Tiêu đề HTTP

Bạn có thể sử dụng chú thích @HeaderParam nếu bạn muốn truyền tham số qua các tiêu đề HTTP:

@POST
@Path("/create")
public void create(@HeaderParam("param1") String param1,
                   @HeaderParam("param2") String param2) {
    ...
}

Đây là thông điệp HTTP sẽ như thế nào. Lưu ý rằng POST này không có cơ thể.

POST /create HTTP/1.1
Content-Length: 0
Host: www.example.com
param1: hello
param2: world

Tôi sẽ không sử dụng phương pháp này để truyền tham số tổng quát. Nó thực sự tiện dụng nếu bạn cần truy cập giá trị của một tiêu đề HTTP cụ thể.


Tham số truy vấn HTTP

Phương pháp này chủ yếu được sử dụng với HTTP GET nhưng nó cũng có thể áp dụng tương tự cho POST. Nó sử dụng chú thích @QueryParam .

@POST
@Path("/create")
public void create(@QueryParam("param1") String param1,
                   @QueryParam("param2") String param2) {
    ...
}

Giống như kỹ thuật trước đó, việc truyền tham số qua chuỗi truy vấn không yêu cầu phần thân thông báo. Đây là thông điệp HTTP:

POST /create?param1=hello&param2=world HTTP/1.1
Content-Length: 0
Host: www.example.com

Bạn phải đặc biệt cẩn thận để mã hóa chính xác các tham số truy vấn ở phía máy khách. Việc sử dụng các tham số truy vấn có thể có vấn đề do các hạn chế về độ dài URL được thi hành bởi một số proxy cũng như các vấn đề liên quan đến mã hóa chúng.


Tham số đường dẫn HTTP

Các tham số đường dẫn tương tự như các tham số truy vấn ngoại trừ việc chúng được nhúng trong đường dẫn tài nguyên HTTP. Phương pháp này dường như được ủng hộ ngày hôm nay. Có những tác động liên quan đến bộ nhớ đệm HTTP vì đường dẫn là thứ thực sự xác định tài nguyên HTTP. Mã trông hơi khác so với các mã khác vì chú thích @Path được sửa đổi và nó sử dụng @PathParam :

@POST
@Path("/create/{param1}/{param2}")
public void create(@PathParam("param1") String param1,
                   @PathParam("param2") String param2) {
    ...
}

Thông báo tương tự như phiên bản tham số truy vấn ngoại trừ tên của các tham số không được bao gồm ở bất kỳ đâu trong thông báo.

POST /create/hello/world HTTP/1.1
Content-Length: 0
Host: www.example.com

Phương pháp này chia sẻ cùng một tai ương mã hóa mà phiên bản tham số truy vấn. Các đoạn đường dẫn được mã hóa khác nhau, do đó bạn cũng phải cẩn thận.


Như bạn có thể thấy, có những ưu và nhược điểm đối với từng phương pháp. Sự lựa chọn thường được quyết định bởi khách hàng của bạn. Nếu bạn đang phục vụ FORMcác trang HTML dựa trên, thì hãy sử dụng @FormParam. Nếu khách hàng của bạn là JavaScript + dựa trên HTML5, thì có lẽ bạn sẽ muốn sử dụng các đối tượng JSON và tuần tự hóa dựa trên JAXB. Việc MessageBodyReader/Writertriển khai nên quan tâm đến việc thoát hiểm cần thiết cho bạn để đó là một điều ít có thể sai. Nếu ứng dụng khách của bạn dựa trên Java nhưng không có bộ xử lý XML tốt (ví dụ: Android), thì tôi có thể sẽ sử dụng FORMmã hóa vì phần thân nội dung dễ tạo và mã hóa chính xác hơn URL. Hy vọng mục nhập wiki nhỏ này làm sáng tỏ các phương pháp khác nhau mà JAX-RS hỗ trợ.

Lưu ý: vì lợi ích của việc tiết lộ đầy đủ, tôi chưa thực sự sử dụng tính năng này của Jersey. Chúng tôi đã mày mò với nó vì chúng tôi có một số ứng dụng JAXB + JAX-RS được triển khai và đang di chuyển vào không gian máy khách di động. JSON phù hợp hơn nhiều với XML trên các giải pháp dựa trên HTML5 hoặc jQuery.


4
Tôi đã thử tính năng này ngày hôm qua, không cần chú thích
@XmlEuity

Cảm ơn vì điều đó. Nếu tôi vẫn muốn gửi 2 Chuỗi thì phần còn lại cần gì để có thể tiêu thụ? Hoặc nhiều thông số chỉ hoạt động với @PathParm?
Klaasvaak

1
@Klaasvaak - bạn cần xác định nơi mỗi param được dự kiến ​​sẽ được trích xuất từ ​​đó. Như bạn có mọi thứ bây giờ Jersey / NetBeans đang giả định một bài đăng mẫu và trích xuất dữ liệu được gửi dưới dạng FormParm. Chú thích từng gia tăng phương thức của bạn với nơi bạn muốn dữ liệu từ (PathParam, FormParam, CookieParam, v.v.)
Nhận thức

1
@Klaasvaak - Tôi đã thêm một loạt các ví dụ bằng cách sử dụng các chú thích khác nhau
D.Shawley

2
Cám ơn bạn rất nhiều về điều này. Đây thực sự là những gì tôi đang tìm kiếm. Bạn đã thực hiện một ngày của tôi;) Tôi đang sử dụng FormParams ngay bây giờ và nó hoạt động!
Klaasvaak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.