Bagaimana cara menggunakan filter servlet di Jawa untuk mengubah url permintaan servlet yang masuk?

186

Bagaimana saya bisa menggunakan filter servlet untuk mengubah url permintaan servlet masuk

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

untuk

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

?


Pembaruan : menurut langkah-langkah BalusC di bawah ini, saya membuat kode berikut:

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

Entri yang relevan web.xmlterlihat seperti ini:

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

Saya mencoba pengalihan sisi server dan sisi klien dengan hasil yang diharapkan. Berhasil, terima kasih BalusC!

jujur
sumber
Pertanyaan terkait: stackoverflow.com/questions/2723829/…
BalusC
Versi servlet spec mana yang Anda gunakan? Cara Anda meneruskan permintaan berubah dengan versi yang berbeda.
Romain Hippeau
Lihat posting ini juga memiliki Filter yang melakukan apa yang Anda inginkan
Romain Hippeau
Harap perhatikan bahwa jika URL asli Anda berisi parameter, yaitu nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B ** maka parameter ini juga akan diteruskan ke servlet / jsp berikutnya. Saya tidak menemukan cara untuk menyingkirkan atau mengganti parameter asli (hanya dengan menggunakan HttpServletRequestWrapper). Ada gagasan? .. Perbarui: tampaknya http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ mengatasi masalah ini.
Lopotun
Terima kasih saya sedang mencari contoh penulisan ulang url dan enkripsi.
Aditya Yada

Jawaban:

281
  1. Implementasikan javax.servlet.Filter.
  2. Dalam doFilter()metode, masukkan yang masuk ServletRequestke HttpServletRequest.
  3. Gunakan HttpServletRequest#getRequestURI()untuk mengambil jalan.
  4. Gunakan langsung java.lang.Stringmetode seperti substring(), split(), concat()dan sebagainya untuk mengekstrak bagian dari bunga dan menyusun jalan baru.
  5. Gunakan salah satu ServletRequest#getRequestDispatcher()dan kemudian RequestDispatcher#forward()untuk meneruskan permintaan / tanggapan ke URL baru (pengalihan sisi-server, tidak tercermin di bilah alamat browser), atau masukkan yang masuk ServletResponseke HttpServletResponsedan kemudian HttpServletResponse#sendRedirect()untuk mengarahkan tanggapan ke URL baru (pengalihan sisi klien, tercermin dalam bilah alamat browser).
  6. Daftar filter di web.xmlpada url-patterndari /*atau /Check_License/*, tergantung pada jalur konteks, atau jika Anda berada di Servlet 3.0 sudah, gunakan @WebFilterpenjelasan untuk itu sebagai gantinya.

Jangan lupa untuk menambahkan tanda centang pada kode jika URL perlu diubah dan jika tidak , maka panggil saja FilterChain#doFilter(), kalau tidak maka akan memanggil dirinya sendiri dalam loop tak terbatas.

Atau Anda juga dapat menggunakan API pihak ke-3 yang ada untuk melakukan semua pekerjaan untuk Anda, seperti UrlRewriteFilter Tuckey yang dapat dikonfigurasi dengan cara seperti yang akan Anda lakukan dengan Apache mod_rewrite.

BalusC
sumber
1
Adakah kode sampel doFilter () di suatu tempat yang melakukan hal di atas? Terima kasih.
Frank
20
Pada langkah apa tepatnya Anda berhenti? Jawaban saya hampir menulis kode itu sendiri. Apakah Anda juga mencatat bahwa referensi kode berwarna biru sebenarnya adalah tautan ke Javadocs yang menjelaskan perilaku kelas / metode secara detail? Bagaimanapun, Anda dapat menemukan di sini dan di sini tutorial JSP / Servlet yang bagus, khususnya yang ini tentang filter.
BalusC
1
Saya kira itu benar, tetapi jika filter adalah salah satu yang pertama dalam rantai, dan RequestDispatcher#forward()dieksekusi, sisa filter tidak akan dieksekusi. Jadi, bukankah cara yang lebih baik untuk melakukan ini sebagai servlet?
lucasvc
2
@dakeake: cukup susun ulang pemesanan atau tambahkan <dispatcher>FORWARD</dispatcher>ke filter filter.
BalusC
1
@ JimJim2000: cukup atur ulang urutan atau tambahkan <dispatcher>FORWARD</dispatcher>ke filter filter.
BalusC
21

Anda dapat menggunakan Filter Url Rewrite yang siap digunakan dengan aturan seperti ini:

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

Periksa Contoh untuk lebih banyak ... contoh.

Thivent Pascal
sumber
7

Filter JSF Url Prettyfier sederhana yang didasarkan pada langkah-langkah jawaban BalusC . Filter meneruskan semua permintaan yang dimulai dengan jalur / ui (seandainya Anda memiliki semua file xhtml Anda yang tersimpan di sana) ke jalur yang sama, tetapi menambahkan akhiran 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 {

    }

}
Biker Xtreme
sumber