2012-11-15 6 views
10
<servlet-mapping> 
    <servlet-name>testServlet</servlet-name> 
    <url-pattern>/test/*</url-pattern> 
</servlet-mapping> 

Nếu tôi nhấn /kiểm tra/trang thì ở trên sẽ hoạt động. Tuy nhiên, nhấn /kiểm tra hoặc /test/ sẽ không hoạt động. Tôi đang sử dụng Spring MVC, và lập bản đồ theo yêu cầu của tôi là như sau:Trong một bản đồ servlet trong Spring MVC, làm cách nào để ánh xạ thư mục gốc của một thư mục mẫu url?

@RequestMapping(value = {"","/"}) 

EDIT:

Tôi đang trong quá trình thẩm tra với một dự án độc lập, nhưng điều này dường như là một lỗi với UrlPathHelper của Spring. Phương thức sau trả về một đường dẫn không chính xác khi có cả ngữ cảnh và đường dẫn servlet, và bạn nhấn servlet mà không có dấu gạch chéo.

public String getPathWithinApplication(HttpServletRequest request) { 
    String contextPath = getContextPath(request); 
    String requestUri = getRequestUri(request); 
    if (StringUtils.startsWithIgnoreCase(requestUri, contextPath)) { 
     // Normal case: URI contains context path. 
     String path = requestUri.substring(contextPath.length()); 
     return (StringUtils.hasText(path) ? path : "/"); 
    } 
    else { 
     // Special case: rather unusual. 
     return requestUri; 
    } 
} 

Cũng như một ví dụ giả sử tôi có một bối cảnh của "admin" và servlet-mapping sau:

<servlet-mapping> 
    <servlet-name>usersServlet</servlet-name> 
    <url-pattern>/users/*</url-pattern> 
</servlet-mapping> 

Bây giờ tôi có một ánh xạ theo yêu cầu tại một trong các bộ điều khiển của tôi như thế này:

@RequestMapping(value = {"","/"}) 

Nếu tôi nhấn /admin/users nó sẽ không hoạt động. Tuy nhiên, nếu tôi nhấn /admin/users/ thì nó sẽ hoạt động. Bây giờ nếu tôi thay đổi bản đồ yêu cầu của tôi như sau sau đó họ sẽ làm việc cả:

@RequestMapping(value = {"/users","/"}) 

Tuy nhiên, bây giờ URL /admin/người dùng/người dùng cũng sẽ làm việc (mà không phải là những gì tôi muốn).

Trả lời

2

Trước hết, sự khác biệt giữa servlet điều phối ánh xạ tới "/" và "/ *". Có sự khác biệt!

Khi ánh xạ tới "/ *", tất cả các yêu cầu URL (bao gồm một cái gì đó như thế này "/WEB-INF/jsp/.../index.jsp") được ánh xạ tới servatcher điều phối. Thứ hai, khi sử dụng Spring + Tiles và trả về một số JSP trong định nghĩa lát của bạn, nó được coi là yêu cầu chuyển tiếp nội bộ và được xử lý bởi cùng một servlet như yêu cầu ban đầu. Trong ví dụ của tôi, tôi gọi URL gốc "/", được nắm bắt đúng bởi phương thức home() và sau đó được chuyển tiếp tới "index.jsp" bởi Tiles, một lần nữa được xử lý bởi Dispatcher Servlet. Rõ ràng, bộ điều phối servlet không thể xử lý "index.jsp", bởi vì không có bộ điều khiển cho nó.

Vâng, nó rất xấu, nhưng có vẻ như đây là cách nó hoạt động.

Vì vậy, giải pháp duy nhất tôi đã tìm thấy cho đến nay: để thay đổi "/ *" trở lại "/" trong web.xml. Bằng cách này, các JSP được kết xuất đúng bởi servlet jsp của Tomcat, tôi đoán, và không phải là servlet dispatcher. Thật không may, sửa chữa này sẽ phá vỡ các URL ROOT cử bởi mùa xuân, vì vậy bạn cần phải rời khỏi ý tưởng sử dụng ROOT URL + Gạch cho bây giờ.

Xin lưu ý rằng việc thêm bản đồ servlet rõ ràng ".jsp -> Tomcat jsp trong web.xml không được, khi sử dụng "/ *", và nó sucks

Tuy nhiên vấn đề không được giải quyết. .

Ngoài ra đây là vấn đề trong Spring MVC 3,0

+0

Sự cố không phải là sử dụng đường dẫn gốc. Nếu tôi sử dụng đường dẫn gốc thì tôi luôn đi với '/' và '@RequestMapping (giá trị = {" ","/"})'. Tôi đã không bao giờ có một vấn đề với điều đó, và tôi đang sử dụng Gạch 2 và Spring MVC 3. Vấn đề là với xác định một đường dẫn servlet đầu tiên. Bất cứ khi nào bạn chỉ định thông tin đường dẫn servlet, ánh xạ yêu cầu của Spring là mọi thứ sau đó. Vì vậy, về mặt kỹ thuật, cùng một ánh xạ yêu cầu sẽ làm việc vì nó là gốc của đường dẫn servlet. Tuy nhiên, đó không phải là trường hợp. –

3

thiết lập của tôi thường trông như thế này:

<servlet-mapping> 
    <servlet-name>testServlet</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

điều khiển, nơi mà tôi giả sử bạn muốn xử lý /test/test/ không kém:

@Controller 
public class MyController { 

    @RequestMapping("/test") 
    public String test() { 
     return "redirect:/welcome"; 
    } 

    @RequestMapping("/test/") 
    public String test() { 
     return "redirect:/welcome"; 
    } 

    @RequestMapping("/welcome") 
    public void test(ModelMap model) { 
     // do your stuff 
    } 
} 

thiết lập như thế này sẽ gây ra DispatcherServlet để xử lý các yêu cầu cho *.css*.js tệp không mong muốn trong hầu hết các trường hợp. tôi nghĩ rằng đây là vấn đề Bhavik mô tả. Đối với những tài nguyên mà bạn có thể cho bạn những ResourceController như thế này:

<mvc:resources mapping="/css/**" location="/resources/css/" /> 
<mvc:resources mapping="/js/**" location="/resources/js/" /> 

tập tin từ /resources/css/resources/js sẽ được phục vụ mà không buộc bạn phải viết một bộ điều khiển phụ.

+0

Tôi nghĩ rằng điều này sẽ không hoạt động như bộ điều khiển gốc –

+0

@BhavikAmbani tại sao không? – Yevgeniy

+0

Câu hỏi là về bộ điều khiển gốc, để tham khảo thêm hãy đọc câu trả lời dưới đây của tôi –

4

Yevgeniy là đúng, nhưng nếu DispatcherServlet của bạn được tiếp quản cho servlet mặc định, bạn phải thêm video này vào web.xml của bạn:

<welcome-file-list> 
    <welcome-file>/</welcome-file> 
</welcome-file-list> 
+0

Tôi không lạ , Đó là con đường đúng! –

0

Một cách mà không liên lạc các tập tin web.xml là bởi bộ bản đồ đến đường dẫn tệp chào mừng mặc định.

@RequestMapping("/index.html") 
0

Trong trường hợp của tôi, mỗi url đang làm việc trừ gốc "/" url.
Vấn đề là tôi đã không xóa tệp index.htm bên trong thư mục gốc webapp của dự án của tôi.