วิธีใช้ตัวกรอง servlet ใน Java เพื่อเปลี่ยน URL ที่ร้องขอของเซิร์ฟเล็ตขาเข้า


186

ฉันจะใช้ตัวกรอง servlet เพื่อเปลี่ยน url คำขอเข้ามาได้อย่างไร

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

ถึง

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

?


อัปเดต : ตามขั้นตอนของ BalusC ด้านล่างฉันมาพร้อมกับรหัสต่อไปนี้:

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() {
        //
    }
}

รายการที่เกี่ยวข้องweb.xmlมีลักษณะดังนี้:

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

ฉันลองเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ด้วยผลลัพธ์ที่คาดหวัง มันใช้งานได้ดีขอบคุณ BalusC!


คำถามที่เกี่ยวข้อง: stackoverflow.com/questions/2723829/…
BalusC

คุณใช้สเป็คเซิร์ฟเล็ตรุ่นใด วิธีที่คุณส่งต่อคำขอเปลี่ยนแปลงด้วยเวอร์ชันที่ต่างกัน
Romain Hippeau

ดูโพสต์นี้มันยังมีตัวกรองที่ทำในสิ่งที่คุณต้องการ
Romain Hippeau

โปรดทราบว่าหาก URL ดั้งเดิมของคุณมีพารามิเตอร์เช่นnm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B ** พารามิเตอร์เหล่านี้จะถูกส่งต่อไปยัง servlet / jsp ถัดไป ฉันไม่พบวิธีกำจัดหรือเปลี่ยนพารามิเตอร์ดั้งเดิม (โดยใช้ HttpServletRequestWrapper เท่านั้น) ความคิดใด ๆ .. การปรับปรุง: ดูเหมือนว่าhttp://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ที่อยู่ปัญหานี้
Lopotun

ขอบคุณฉันค้นหาตัวอย่างในการเขียน url และการเข้ารหัสใหม่
Aditya Yada

คำตอบ:


281
  1. javax.servlet.FilterImplement
  2. ในdoFilter()วิธีการโยนเข้ามาเพื่อServletRequestHttpServletRequest
  3. ใช้HttpServletRequest#getRequestURI()เพื่อคว้าเส้นทาง
  4. ใช้java.lang.Stringวิธีการตรงไปตรงมาเช่นsubstring() , split(), concat()และอื่น ๆ เพื่อดึงส่วนหนึ่งที่น่าสนใจและเขียนเส้นทางใหม่
  5. ใช้อย่างใดอย่างหนึ่งServletRequest#getRequestDispatcher()แล้วRequestDispatcher#forward()ส่งต่อคำขอ / ตอบกลับไปยัง URL ใหม่ (การเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์ไม่ปรากฏในแถบที่อยู่ของเบราว์เซอร์) หรือส่งข้อความขาเข้าServletResponseไปHttpServletResponseแล้วHttpServletResponse#sendRedirect()ที่จะเปลี่ยนเส้นทางการตอบสนองต่อ URL ใหม่ (ด้านลูกค้าเปลี่ยนเส้นทางสะท้อนให้เห็นใน แถบที่อยู่ของเบราว์เซอร์)
  6. ลงทะเบียนตัวกรอง web.xmlบนurl-patternของ/*หรือ/Check_License/*ขึ้นอยู่กับเส้นทางบริบทหรือถ้าคุณอยู่ใน Servlet 3.0 แล้วใช้@WebFilterคำอธิบายประกอบสำหรับที่แทน

อย่าลืมเพิ่มการตรวจสอบในรหัสถ้า URL ความต้องการจะมีการเปลี่ยนแปลงและหากไม่แล้วก็เรียกFilterChain#doFilter()อื่นก็จะเรียกตัวเองในวง จำกัด

นอกจากนี้คุณยังสามารถใช้ API บุคคลที่สามที่มีอยู่เพื่อทำงานทั้งหมดให้กับคุณเช่นUrlRewriteFilter ของ Tuckeyซึ่งสามารถกำหนดค่าได้ตามที่คุณต้องการกับ Apachemod_rewriteApache


1
มีตัวอย่างโค้ด doFilter () ใดที่ทำข้างต้นหรือไม่ ขอบคุณ
แฟรงค์

20
ในขั้นตอนใดที่คุณติดอยู่ คำตอบของฉันเกือบจะเขียนโค้ดเอง คุณยังทราบด้วยว่าการอ้างอิงรหัสเป็นสีน้ำเงินนั้นจริง ๆ แล้วลิงก์ไปยัง Javadocs ซึ่งอธิบายพฤติกรรม / วิธีการเรียนอย่างละเอียด ในทางใดทางหนึ่งคุณสามารถหาได้ที่นี่และที่นี่ดีบทเรียน JSP / Servlet เฉพาะนี้อย่างใดอย่างหนึ่งเกี่ยวกับตัวกรอง
BalusC

1
ฉันคิดว่ามันถูกต้อง แต่ถ้าตัวกรองเป็นหนึ่งในอันดับแรกในห่วงโซ่และRequestDispatcher#forward()ถูกดำเนินการส่วนที่เหลือของตัวกรองจะไม่ถูกดำเนินการ ดังนั้นจะไม่เป็นวิธีที่ดีกว่าแล้วทำเช่นนี้เป็น servlet หรือไม่
lucasvc

2
@datakey: เพียงแค่เรียงลำดับการจัดเรียงใหม่หรือเพิ่ม<dispatcher>FORWARD</dispatcher>ในการกรองการแมป
BalusC

1
@ JimJim2000: เพียงแค่เรียงลำดับการจัดเรียงใหม่หรือเพิ่ม<dispatcher>FORWARD</dispatcher>การกรองการแมป
BalusC


7

กรอง JSF Url Prettyfier ง่ายอยู่ในขั้นตอนของคำตอบของ BalusC ตัวกรองส่งต่อคำขอทั้งหมดที่เริ่มต้นด้วยเส้นทาง / ui (หากคุณมีไฟล์ xhtml ทั้งหมดของคุณเก็บไว้ที่นั่น) ไปยังเส้นทางเดียวกัน แต่เพิ่มส่วนต่อท้าย 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 {

    }

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.