Làm cách nào để sử dụng bộ lọc servlet trong Java để thay đổi url yêu cầu của servlet đến?


186

Làm cách nào tôi có thể sử dụng bộ lọc servlet để thay đổi url yêu cầu của servlet đến từ

http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123

đến

http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123

?


Cập nhật : theo các bước của BalusC bên dưới, tôi đã đưa ra mã sau:

public class UrlRewriteFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();

        if (requestURI.startsWith("/Check_License/Dir_My_App/")) {
            String toReplace = requestURI.substring(requestURI.indexOf("/Dir_My_App"), requestURI.lastIndexOf("/") + 1);
            String newURI = requestURI.replace(toReplace, "?Contact_Id=");
            req.getRequestDispatcher(newURI).forward(req, res);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

Các mục có liên quan trong web.xmlnhư thế này:

<filter>
    <filter-name>urlRewriteFilter</filter-name>
    <filter-class>com.example.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>urlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Tôi đã thử cả chuyển hướng phía máy chủ và phía máy khách với kết quả mong đợi. Nó hoạt động, cảm ơn BalusC!



Phiên bản nào của thông số kỹ thuật bạn đang sử dụng? Cách bạn chuyển tiếp yêu cầu thay đổi với các phiên bản khác nhau.
Romain Hippeau

Xem bài đăng này, nó cũng có Bộ lọc thực hiện những gì bạn muốn
Romain Hippeau

Xin lưu ý rằng nếu URL ban đầu của bạn chứa các tham số, ví dụ: nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B ** thì các tham số này cũng sẽ được chuyển tiếp tới servlet / jsp tiếp theo. Tôi đã không tìm ra cách để loại bỏ hoặc thay thế các tham số ban đầu (chỉ bằng cách sử dụng HttpServletRequestWrapper). Có ý tưởng nào không? .. Cập nhật: có vẻ như http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ giải quyết vấn đề này.
Lopotun

Cảm ơn tôi đã tìm kiếm một ví dụ về viết lại url và mã hóa.
Aditya Yada

Câu trả lời:


281
  1. Thực hiện javax.servlet.Filter.
  2. Trong doFilter()phương pháp, cast đến ServletRequestđể HttpServletRequest.
  3. Sử dụng HttpServletRequest#getRequestURI()để lấy đường dẫn.
  4. Sử dụng đơn giản java.lang.Stringphương pháp như substring(), split(), concat()và vân vân để trích xuất một phần của lợi ích và soạn con đường mới.
  5. Sử dụng một trong hai ServletRequest#getRequestDispatcher()và sau đó RequestDispatcher#forward()để chuyển tiếp yêu cầu / phản hồi tới URL mới (chuyển hướng phía máy chủ, không được phản ánh trên thanh địa chỉ trình duyệt) hoặc chuyển ServletResponseđến HttpServletResponsevà sau đó HttpServletResponse#sendRedirect()để chuyển hướng phản hồi tới URL mới (chuyển hướng phía máy khách, được phản ánh trong thanh địa chỉ trình duyệt).
  6. Đăng ký bộ lọc web.xmltrên một url-patternsố /*hoặc /Check_License/*, tùy thuộc vào đường dẫn ngữ cảnh, hoặc nếu bạn đang ở trên Servlet 3.0 đã có, sử dụng @WebFilterchú thích cho điều đó để thay thế.

Đừng quên thêm một kiểm tra trong mã nếu URL cần được thay đổi và nếu không , sau đó chỉ cần gọi FilterChain#doFilter(), nếu không nó sẽ tự gọi trong một vòng lặp vô hạn.

Ngoài ra, bạn cũng có thể sử dụng API của bên thứ 3 hiện tại để thực hiện tất cả công việc cho mình, chẳng hạn như UrlRewriteFilter của Tuckey có thể được định cấu hình theo cách bạn sẽ làm với Apache mod_rewrite.


1
Bất kỳ mã mẫu doFilter () ở đâu đó không thực hiện ở trên? Cảm ơn.
Frank

20
Ở bước nào chính xác là bạn đang bị mắc kẹt? Câu trả lời của tôi gần như viết mã chính nó. Bạn có lưu ý rằng các tham chiếu mã màu xanh lam thực sự là các liên kết đến Javadocs mô tả chi tiết hành vi của lớp / phương thức không? Bằng bất cứ cách nào, bạn có thể tìm thấy ở đâyở đây các hướng dẫn tốt về JSP / Servlet, cụ thể là hướng dẫn này về các bộ lọc.
BalusC

1
Tôi cho rằng nó là chính xác, nhưng nếu bộ lọc là một trong những cái đầu tiên trong chuỗi và RequestDispatcher#forward()được thực thi, phần còn lại của các bộ lọc sẽ không được thực thi. Vì vậy, sẽ không phải là một cách tốt hơn sau đó làm điều này như một servlet?
lucasvc

2
@datakey: chỉ cần sắp xếp lại thứ tự hoặc thêm <dispatcher>FORWARD</dispatcher>vào ánh xạ bộ lọc.
BalusC

1
@ JimJim2000: chỉ cần sắp xếp lại thứ tự hoặc thêm <dispatcher>FORWARD</dispatcher>vào ánh xạ bộ lọc.
BalusC

21

Bạn có thể sử dụng Bộ lọc Viết lại Url sẵn sàng với quy tắc như thế này:

<rule>
  <from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
  <to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>

Kiểm tra các ví dụ để biết thêm ... ví dụ.


7

Một bộ lọc UF Prettyfier đơn giản dựa trên các bước trả lời của BalusC . Bộ lọc chuyển tiếp tất cả các yêu cầu bắt đầu bằng đường dẫn / ui (giả sử bạn đã có tất cả các tệp xhtml được lưu trữ ở đó) vào cùng một đường dẫn, nhưng thêm hậu tố xhtml.

public class UrlPrettyfierFilter implements Filter {

    private static final String JSF_VIEW_ROOT_PATH = "/ui";

    private static final String JSF_VIEW_SUFFIX = ".xhtml";

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
        String requestURI = httpServletRequest.getRequestURI();
        //Only process the paths starting with /ui, so as other requests get unprocessed. 
        //You can register the filter itself for /ui/* only, too
        if (requestURI.startsWith(JSF_VIEW_ROOT_PATH) 
                && !requestURI.contains(JSF_VIEW_SUFFIX)) {
            request.getRequestDispatcher(requestURI.concat(JSF_VIEW_SUFFIX))
                .forward(request,response);
        } else {
            chain.doFilter(httpServletRequest, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}
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.