2014-12-11 22 views
10

Tôi đang cố gắng thiết lập điểm cuối REST cho phép truy vấn người dùng theo địa chỉ email của họ. Địa chỉ email là phần cuối cùng của đường dẫn để Spring xử lý [email protected] làm giá trị [email protected] và cắt bớt phần mở rộng .com.Mùa xuân - Biến đường cắt sau dấu chấm - chú thích

Tôi tìm thấy câu hỏi tương tự ở đây Spring MVC @PathVariable with dot (.) is getting truncated Tuy nhiên, tôi có cấu hình dựa trên chú thích sử dụng AbstractAnnotationConfigDispatcherServletInitializerWebMvcConfigurerAdapter. Vì tôi không có cấu hình xml, giải pháp này sẽ không hoạt động đối với tôi:

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="useDefaultSuffixPattern" value="false" /> 
</bean> 

Tôi cũng đã thử giải pháp này sử dụng regex nhưng chưa hoạt động.

@RequestMapping(value = "user/by-email/{email:.+}") 

Có ai biết cách tắt cắt mẫu hậu tố mà không có xml không?

+0

thực hiện [this] (https://github.com/resthub/resthub-spring-stack/issues/188) giúp bạn –

Trả lời

18

Dấu chấm trong biến đường dẫn ở cuối URI gây ra hai hành vi không mong muốn (bất ngờ đối với đa số người dùng, trừ những người quen thuộc với số lượng lớn thuộc tính cấu hình Spring).

Đầu tiên (trong đó có thể được khắc phục bằng cách sử dụng chế độ xem {email:.+}) là cấu hình Spring mặc định khớp với tất cả tiện ích đường dẫn. Vì vậy, thiết lập ánh xạ cho /api/{file} sẽ có nghĩa là Spring ánh xạ cuộc gọi đến /api/myfile.html đến đối số Chuỗi myfile. Điều này hữu ích khi bạn muốn /api/myfile.html, /api/myfile.md, /api/myfile.txt và các thiết bị khác trỏ đến cùng một tài nguyên. Tuy nhiên, chúng tôi có thể tắt hành vi này trên toàn cầu, mà không cần phải sử dụng chức năng hack regex trên mọi điểm cuối.

Vấn đề thứ hai liên quan đến lần đầu tiên và được sửa lỗi chính xác bởi @masstroy. Khi /api/myfile.* trỏ đến tài nguyên myfile, Spring giả định tiện ích đường dẫn (.html, .txt, v.v.) cho biết rằng tài nguyên phải được trả lại bằng định dạng cụ thể. Hành vi này cũng có thể rất hữu ích trong một số trường hợp. Nhưng thông thường, điều đó có nghĩa là đối tượng được trả về bởi ánh xạ phương thức không thể được chuyển đổi thành định dạng này và Spring sẽ ném một số HttpMediaTypeNotAcceptableException.

Chúng tôi có thể biến cả tắt như sau (giả sử mùa xuân Boot):

@Configuration 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void configurePathMatch(PathMatchConfigurer configurer) { 
    // turn off all suffix pattern matching 
    configurer.setUseSuffixPatternMatch(false); 
    // OR 
    // turn on suffix pattern matching ONLY for suffixes 
    // you explicitly register using 
    // configureContentNegotiation(...) 
    configurer.setUseRegisteredSuffixPatternMatch(true); 
    } 

    @Override 
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
    configurer.favorPathExtension(false); 
    } 
} 

Thông tin thêm về Content Negotiation.

7

Tôi đã tìm thấy giải pháp này bằng cách sử dụng đậu ContentNegotiationConfigurer từ bài viết này: http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc

tôi đã thêm các cấu hình sau đến lớp webconfig của tôi:

@EnableWebMvc 
@Configuration 
@ComponentScan(basePackageClasses = { RestAPIConfig.class }) 
public class WebConfig extends WebMvcConfigurerAdapter {  
    @Override 
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
     configurer.favorPathExtension(false); 
     configurer.defaultContentType(MediaType.APPLICATION_JSON); 
    } 
} 

Bằng cách đặt .favorPathExtension(false), mùa xuân sẽ không còn sử dụng phần mở rộng tệp để ghi đè lên phương tiện chấp nhận loại yêu cầu. Javadoc cho phương pháp mà đọc Indicate whether the extension of the request path should be used to determine the requested media type with the highest priority.

Sau đó, tôi lập @RequestMapping của tôi bằng cách sử dụng regex

@RequestMapping(value = "/user/by-email/{email:.+}") 
+0

Lưu ý rằng thay vì sử dụng '{email:. +}' Hack bạn cũng có thể tắt kết hợp mẫu hậu tố bằng cách ghi đè 'WebMvcConfigurerAdapter.configurePathMatch (PathMatcherConfigurer configurer)' và thiết lập 'configurer.setUseSuffixPatternMatch (false)'. Bạn cũng có thể hạn chế mẫu phù hợp với phần mở rộng tệp được đăng ký rõ ràng. – bkjvbx

+0

{email:. +} Đã hoạt động cho tôi mà không có bất kỳ cấu hình bổ sung nào. Điều đó có nghĩa là nó không cắt một phần sau dấu chấm. Nhưng có một vấn đề khác. ExceptionHandler không hoạt động đúng với các biến chấm. Giải pháp của bạn đã khắc phục vấn đề đó cũng như – jasiustasiu

+0

@bkjvbx bạn có thể đăng giải pháp của mình làm câu trả lời, có vẻ tốt hơn câu trả lời này và tôi sẽ đánh dấu nó là câu trả lời được chấp nhận – masstroy

0

Đối với các folks Java-Config:

Với mùa xuân 4 bạn chỉ có thể tắt tính năng này bằng cách:

@Configuration 
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void configurePathMatch(PathMatchConfigurer configurer) { 
    configurer.setUseSuffixPatternMatch(false); 
    } 

} 

Sau đó, trong các dấu chấm ứng dụng toàn bộ sẽ xử lý như dấu chấm.

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