2012-06-21 29 views
14

Có một phương pháp như thế này:Tomcat, JAX-RS, Jersey, @PathParam: cách vượt qua dấu chấm và dấu gạch chéo?

@GET @Path("/name/{name}") 
@Produces(MediaType.TEXT_PLAIN) 
public String getProperty(@PathParam("name") String name) { 
     System.out.println(name); 
} 

Làm thế nào để vượt qua một giá trị như "test./test"?

/name/test./test  gives HTTP 404 
/name/test.%2Ftest gives HTTP 400 
/name/test.%252Ftest prints test%2Ftest 

Nhưng nếu tôi làm name = URLDecoder.decode(name); nó in /test và phần đầu của test. biến mất.

Có một hoặc hai câu hỏi như thế này nhưng chúng đã cũ và không tìm thấy giải pháp tốt nào, tôi nghĩ tôi sẽ hỏi lại.

Trả lời

21

Các mô hình trong @Path chú thích được nội biến thành một biểu thức chính quy, với các mẫu phụ tùng phù hợp với nhân vật duy nhất được lựa chọn theo mặc định. Đặc biệt, chúng thường là không khớp với / ký tự; đó là hầu như luôn luôn là điều đúng để làm (vì nó cho phép bạn đặt mẫu một phần cách thức thông qua một con đường) nhưng trong trường hợp này nó không phải là bạn đang muốn tiêu thụ toàn bộ đường dẫn tiếp theo. Để có được mọi thứ, chúng ta phải ghi đè lên đoạn biểu thức chính quy cho mẫu cụ thể đó; đây là thực sự khá dễ dàng, vì chúng ta chỉ cần đặt trong các mẫu phân mảnh một : tiếp theo là RE mà chúng ta muốn sử dụng:

@GET @Produces(MediaType.TEXT_PLAIN) 
@Path("/name/{name:.+}") 
public String getProperty(@PathParam("name") String name) { 
    return name; 
} 

này sẽ phù hợp tất cả các ký tự sau khi /name/ (lên đến nhưng không bao gồm bất kỳ truy vấn ? một phần) nhưng sẽ chỉ phù hợp nếu có gì đó ở đó. Xin lưu ý rằng nếu bạn có bất kỳ điều gì khác về @Path("/name/..."), mọi thứ có thể trở nên thực sự khó hiểu! Vậy đừng làm thế.

+1

Hoạt động! Có thể vượt qua bất kỳ số lượng dấu gạch chéo, tất cả đều bị bắt tốt. Điều này sẽ làm việc với tất cả các triển khai JAX-RS hay nó hoạt động như thế nào? Dù bằng cách nào, cảm ơn rất nhiều, nó giải quyết vấn đề của tôi. –

+1

@Maxim Tôi nghĩ đó là tiêu chuẩn và tôi sử dụng nó với Apache CXF. –

+0

Có vẻ đẹp, nhưng có vẻ như dấu gạch chéo ngược không khớp với cụm từ thông dụng này .. – Ievgen

0

Cố gắng xác định loại mã hóa, các công việc sau cho tôi với /name/test.%252Ftest:

System.out.println(URLDecoder.decode(name, "UTF-8")); 
return URLDecoder.decode(name, "UTF-8"); 
+0

Hoạt động! Đã thêm mã hóa và biến "kiểm tra.% 252Ftest" thành "test./test", không chỉ là "/ test". Cảm ơn! –

5

Nếu bạn sử dụng tomcat và muốn vượt qua / trong pathparam. bên cạnh các công cụ @Path("/name/{name:.+}") như 'Nghiên cứu sinh Donal' cho biết, bạn nên thêm -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true vào đối số jvm của mình, xem thêm tomcat security-howto.

+0

Tôi không cần đến điều đó, miễn là đường dẫn có chứa '/' và không phải là mã được mã hóa. –

0

Glassfish v4 chấp nhận hình dạng mã hóa cho dấu gạch chéo% 2f. Sau đó chúng ta có thể vượt qua kiểm tra String được mã hóa% 2Ftest và nhận kết quả kiểm tra./test bằng cách sử dụng URLDecoder.decode (tên, "UTF-8"). Tôi nghĩ rằng đây là một giải pháp tốt hơn, đặc biệt là khi bạn có nhiều thông số trong một yêu cầu. Sử dụng đường dẫn @Path ("/ name/{name:. +}") Là giải pháp tuyệt vời khi chúng tôi có vài tham số trong yêu cầu.

Sử dụng% 252f làm phức tạp yêu cầu của máy khách là cần thiết để đối chiếu yêu cầu mã hóa Chuỗi theo cách thủ công. Với glassfish v4 thật dễ dàng để sử dụng phần trăm mã hóa với URLEncoder.encode trong máy khách và URLDecoder.decode trong máy chủ để chúc Strings. Các ngôn ngữ lập trình nhất có phần trăm mã hóa và giải mã, do đó nó là giải pháp hoàn hảo.

tôi đã cố gắng kích hoạt tính năng mã hóa trong slash v3 glassfish nhưng không thành công, đây là sintaxe tôi đã cố gắng sử dụng

bin \ asadmin thiết configs.config.server-config.network-config.protocols.protocol.http-listener -1.http.encoded-slash-enabled = true configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.encoded-slash-enabled = true

Lệnh được thi hành thành công.

Kính trọng Cassio Seffrin

Các vấn đề liên quan