Panduan Pola Pengontrol Depan di Java

1. Ikhtisar

Dalam tutorial ini kita akan menggali lebih dalam Front Controller Pola , bagian dari Pola Perusahaan sebagaimana didefinisikan dalam Martin Fowler buku 's ‘Pola Aplikasi Enterprise Architecture’.

Pengontrol Depan didefinisikan sebagai "pengontrol yang menangani semua permintaan untuk situs Web". Itu berdiri di depan aplikasi web dan mendelegasikan permintaan ke sumber daya berikutnya. Ini juga menyediakan antarmuka untuk perilaku umum seperti keamanan, internasionalisasi dan menyajikan pandangan tertentu kepada pengguna tertentu.

Ini memungkinkan aplikasi untuk mengubah perilakunya saat runtime. Selain itu, membantu membaca dan memelihara aplikasi dengan mencegah duplikasi kode.

Pengontrol Depan menggabungkan semua penanganan permintaan dengan menyalurkan permintaan melalui satu objek penangan.

2. Bagaimana cara kerjanya?

The Front Controller Pola terutama dibagi menjadi dua bagian. Pengontrol pengiriman tunggal dan hierarki perintah. UML berikut menggambarkan hubungan kelas dari implementasi Kontroler Depan generik:

Pengontrol tunggal ini mengirimkan permintaan ke perintah untuk memicu perilaku yang terkait dengan permintaan.

Untuk mendemonstrasikan implementasinya, kita akan mengimplementasikan controller di FrontControllerServlet dan perintah sebagai kelas yang diwarisi dari FrontCommand abstrak .

3. Penyiapan

3.1. Dependensi Maven

Pertama, kami akan menyiapkan proyek Maven WAR baru dengan menyertakan javax.servlet-api :

 javax.servlet javax.servlet-api 4.0.0-b01 provided  

serta jetty-maven-plugin :

 org.eclipse.jetty jetty-maven-plugin 9.4.0.M1   /front-controller   

3.2. Model

Selanjutnya, kita akan mendefinisikan kelas Model dan Repositori model . Kami akan menggunakan kelas Buku berikut sebagai model kami:

public class Book { private String author; private String title; private Double price; // standard constructors, getters and setters }

Ini akan menjadi repositori, Anda dapat mencari kode sumber untuk implementasi konkret atau menyediakannya sendiri:

public interface Bookshelf { default void init() { add(new Book("Wilson, Robert Anton & Shea, Robert", "Illuminati", 9.99)); add(new Book("Fowler, Martin", "Patterns of Enterprise Application Architecture", 27.88)); } Bookshelf getInstance();  boolean add(E book); Book findByTitle(String title); }

3.3. FrontControllerServlet

Implementasi Servlet itu sendiri cukup sederhana. Kami mengekstrak nama perintah dari permintaan, membuat secara dinamis contoh baru dari kelas perintah dan menjalankannya.

Ini memungkinkan kami untuk menambahkan perintah baru tanpa mengubah basis kode Pengontrol Depan kami .

Pilihan lainnya adalah mengimplementasikan Servlet menggunakan statis, logika kondisional. Ini memiliki keuntungan dari pemeriksaan kesalahan waktu kompilasi:

public class FrontControllerServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { FrontCommand command = getCommand(request); command.init(getServletContext(), request, response); command.process(); } private FrontCommand getCommand(HttpServletRequest request) { try { Class type = Class.forName(String.format( "com.baeldung.enterprise.patterns.front." + "controller.commands.%sCommand", request.getParameter("command"))); return (FrontCommand) type .asSubclass(FrontCommand.class) .newInstance(); } catch (Exception e) { return new UnknownCommand(); } } }

3.4. FrontCommand

Mari mengimplementasikan kelas abstrak yang disebut FrontCommand , yang menahan perilaku umum untuk semua perintah.

Kelas ini memiliki akses ke ServletContext serta objek permintaan dan responsnya. Selanjutnya, ini akan menangani resolusi tampilan:

public abstract class FrontCommand { protected ServletContext context; protected HttpServletRequest request; protected HttpServletResponse response; public void init( ServletContext servletContext, HttpServletRequest servletRequest, HttpServletResponse servletResponse) { this.context = servletContext; this.request = servletRequest; this.response = servletResponse; } public abstract void process() throws ServletException, IOException; protected void forward(String target) throws ServletException, IOException { target = String.format("/WEB-INF/jsp/%s.jsp", target); RequestDispatcher dispatcher = context.getRequestDispatcher(target); dispatcher.forward(request, response); } }

Implementasi konkret dari FrontCommand abstrak ini akan menjadi SearchCommand . Ini akan mencakup logika kondisional untuk kasus-kasus di mana sebuah buku ditemukan atau ketika buku hilang:

public class SearchCommand extends FrontCommand { @Override public void process() throws ServletException, IOException { Book book = new BookshelfImpl().getInstance() .findByTitle(request.getParameter("title")); if (book != null) { request.setAttribute("book", book); forward("book-found"); } else { forward("book-notfound"); } } }

Jika aplikasi sedang berjalan, kita dapat mencapai perintah ini dengan mengarahkan browser kita ke // localhost: 8080 / front-controller /? Command = Search & title = patterns.

The SearchCommand resolve ke dua pandangan, pandangan kedua dapat diuji dengan permintaan berikut // localhost: 8080 / front-controller / perintah = Search & title = setiap-judul?.

Untuk melengkapi skenario kami, kami akan menerapkan perintah kedua, yang diaktifkan sebagai fallback dalam semua kasus, permintaan perintah tidak dikenal oleh Servlet:

public class UnknownCommand extends FrontCommand { @Override public void process() throws ServletException, IOException { forward("unknown"); } }

Tampilan ini dapat dijangkau di // localhost: 8080 / front-controller /? Command = Order & title = any-title atau dengan mengabaikan parameter URL sama sekali .

4. Penerapan

Karena kami memutuskan untuk membuat proyek file WAR , kami memerlukan deskriptor penerapan web. Dengan web.xml ini kami dapat menjalankan aplikasi web kami di wadah Servlet apa pun:

   front-controller  com.baeldung.enterprise.patterns.front.controller.FrontControllerServlet    front-controller /  

Sebagai langkah terakhir kita akan menjalankan 'mvn install jetty: run' dan memeriksa tampilan kita di browser.

5. Kesimpulan

Seperti yang telah kita lihat sejauh ini, kita sekarang harus terbiasa dengan Pola Pengontrol Depan dan implementasinya sebagai Servlet dan hierarki perintah.

Seperti biasa, Anda akan menemukan sumbernya di GitHub.