Struts 2 - Bộ đánh chặn

Các bộ đánh chặn về mặt khái niệm giống như bộ lọc servlet hoặc lớp Proxy JDKs. Các bộ đánh chặn cho phép thực hiện chức năng cắt ngang riêng biệt với hành động cũng như khuôn khổ. Bạn có thể đạt được những điều sau đây bằng cách sử dụng các thiết bị đánh chặn -

  • Cung cấp logic tiền xử lý trước khi hành động được gọi.

  • Cung cấp logic hậu xử lý sau khi hành động được gọi.

  • Bắt các ngoại lệ để có thể thực hiện xử lý thay thế.

Nhiều tính năng được cung cấp trong Struts2 khuôn khổ được thực hiện bằng cách sử dụng các thiết bị đánh chặn;

Examples bao gồm xử lý ngoại lệ, tải lên tệp, gọi lại vòng đời, v.v. Thực tế, vì Struts2 nhấn mạnh nhiều chức năng của nó trên các bộ đánh chặn, nên nó không có khả năng được chỉ định 7 hoặc 8 bộ đánh chặn cho mỗi hành động.

Struts2 Framework đánh chặn

Khung công tác Struts 2 cung cấp một danh sách tốt các thiết bị đánh chặn hiện có được cấu hình sẵn và sẵn sàng sử dụng. Một vài trong số các thiết bị đánh chặn quan trọng được liệt kê dưới đây -

Sr.No Đánh chặn & Mô tả
1

alias

Cho phép các tham số có các bí danh tên khác nhau trên các yêu cầu.

2

checkbox

Hỗ trợ quản lý các hộp kiểm bằng cách thêm giá trị tham số là false cho các hộp kiểm không được chọn.

3

conversionError

Đặt thông tin lỗi từ việc chuyển đổi chuỗi thành các loại tham số vào trường lỗi của hành động.

4

createSession

Tự động tạo một phiên HTTP nếu một phiên chưa tồn tại.

5

debugging

Cung cấp một số màn hình gỡ lỗi khác nhau cho nhà phát triển.

6

execAndWait

Đưa người dùng đến trang chờ trung gian trong khi hành động thực hiện ở chế độ nền.

7

exception

Bản đồ các ngoại lệ được chuyển từ một hành động đến một kết quả, cho phép xử lý ngoại lệ tự động thông qua chuyển hướng.

số 8

fileUpload

Tạo điều kiện cho việc tải tệp lên dễ dàng.

9

i18n

Theo dõi ngôn ngữ đã chọn trong phiên của người dùng.

10

logger

Cung cấp ghi nhật ký đơn giản bằng cách xuất ra tên của hành động đang được thực thi.

11

params

Đặt các tham số yêu cầu cho hành động.

12

prepare

Điều này thường được sử dụng để thực hiện công việc tiền xử lý, chẳng hạn như thiết lập kết nối cơ sở dữ liệu.

13

profile

Cho phép thông tin hồ sơ đơn giản được ghi lại cho các hành động.

14

scope

Lưu trữ và truy xuất trạng thái của hành động trong phạm vi phiên hoặc ứng dụng.

15

ServletConfig

Cung cấp hành động với quyền truy cập vào thông tin dựa trên servlet khác nhau.

16

timer

Cung cấp thông tin cấu hình đơn giản dưới dạng thời gian thực thi hành động.

17

token

Kiểm tra hành động để tìm mã thông báo hợp lệ để ngăn việc gửi biểu mẫu trùng lặp.

18

validation

Cung cấp hỗ trợ xác thực cho các hành động

Vui lòng xem tài liệu Struts 2 để biết chi tiết đầy đủ về các thiết bị đánh chặn nói trên. Nhưng tôi sẽ chỉ cho bạn cách sử dụng một bộ đánh chặn nói chung trong ứng dụng Struts của bạn.

Làm thế nào để sử dụng Interceptors?

Hãy để chúng tôi xem cách sử dụng một thiết bị đánh chặn đã có cho chương trình "Hello World" của chúng tôi. Chúng tôi sẽ sử dụngtimerinterceptor có mục đích là đo thời gian thực hiện một phương thức hành động. Đồng thời, tôi đang sử dụngparamsinterceptor có mục đích là gửi các tham số yêu cầu cho hành động. Bạn có thể thử ví dụ của mình mà không cần sử dụng bộ đánh chặn này và bạn sẽ thấy rằngname thuộc tính không được đặt vì thông số không thể truy cập vào hành động.

Chúng tôi sẽ giữ các tệp HelloWorldAction.java, web.xml, HelloWorld.jsp và index.jsp như chúng đã được tạo trong Examples nhưng hãy để chúng tôi sửa đổi struts.xml tệp để thêm một bộ đánh chặn như sau:

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name = "struts.devMode" value = "true" />
   
   <package name = "helloworld" extends = "struts-default">
      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction"
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "timer" />
         <result name = "success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

Nhấp chuột phải vào tên dự án và nhấp vào Export > WAR Fileđể tạo tệp Chiến tranh. Sau đó, triển khai WAR này trong thư mục ứng dụng web của Tomcat. Cuối cùng, khởi động máy chủ Tomcat và cố gắng truy cập URLhttp://localhost:8080/HelloWorldStruts2/index.jsp. Điều này sẽ tạo ra màn hình sau:

Bây giờ nhập bất kỳ từ nào vào hộp văn bản đã cho và nhấp vào nút Nói Xin chào để thực hiện hành động đã xác định. Bây giờ nếu bạn kiểm tra nhật ký được tạo, bạn sẽ tìm thấy văn bản sau:

INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM 
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

Đây là điểm mấu chốt đang được tạo ra vì timer máy đánh chặn thông báo rằng hành động đó mất tổng cộng 109ms để thực hiện.

Tạo các thiết bị chặn tùy chỉnh

Sử dụng các bộ chặn tùy chỉnh trong ứng dụng của bạn là một cách thanh lịch để cung cấp các tính năng ứng dụng cắt ngang. Tạo một thiết bị đánh chặn tùy chỉnh rất dễ dàng; giao diện cần được mở rộng như sauInterceptor giao diện -

public interface Interceptor extends Serializable {
   void destroy();
   void init();
   String intercept(ActionInvocation invocation)
   throws Exception;
}

Như tên gợi ý, phương thức init () cung cấp một cách để khởi tạo bộ đánh chặn và phương thức hủy () cung cấp một cơ sở để dọn dẹp bộ đánh chặn. Không giống như các hành động, các bộ chặn được sử dụng lại trên các yêu cầu và cần phải an toàn cho luồng, đặc biệt là phương thức intercept ().

Các ActionInvocationđối tượng cung cấp quyền truy cập vào môi trường thời gian chạy. Nó cho phép truy cập vào chính hành động và các phương thức để gọi hành động và xác định xem hành động đã được gọi hay chưa.

Nếu bạn không cần mã khởi tạo hoặc dọn dẹp, AbstractInterceptorlớp học có thể được mở rộng. Điều này cung cấp một triển khai không hoạt động mặc định của các phương thức init () và tiêu diệt ().

Tạo lớp đánh chặn

Hãy để chúng tôi tạo MyInterceptor.java sau trong Java Resources > src thư mục -

package com.tutorialspoint.struts2;

import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

   public String intercept(ActionInvocation invocation)throws Exception {

      /* let us do some pre-processing */
      String output = "Pre-Processing"; 
      System.out.println(output);

      /* let us call action or next interceptor */
      String result = invocation.invoke();

      /* let us do some post-processing */
      output = "Post-Processing"; 
      System.out.println(output);

      return result;
   }
}

Như bạn nhận thấy, hành động thực tế sẽ được thực hiện bằng cách sử dụng bộ đánh chặn bằng invocation.invoke()gọi. Vì vậy, bạn có thể thực hiện một số xử lý trước và một số xử lý sau dựa trên yêu cầu của bạn.

Bản thân khung công tác này bắt đầu quá trình bằng cách thực hiện lệnh gọi đầu tiên tới invoke () của đối tượng ActionInvocation. Mỗi lầninvoke()được gọi, ActionInvocation tham khảo trạng thái của nó và thực thi bất kỳ bộ đánh chặn nào đến tiếp theo. Khi tất cả các trình đánh chặn được cấu hình đã được gọi, phương thức invoke () sẽ khiến chính hành động đó được thực thi.

Sơ đồ sau đây cho thấy cùng một khái niệm thông qua một luồng yêu cầu:

Tạo lớp hành động

Hãy để chúng tôi tạo một tệp java HelloWorldAction.java dưới Java Resources > src với một tên gói com.tutorialspoint.struts2 với các nội dung được đưa ra dưới đây.

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {
   private String name;

   public String execute() throws Exception {
      System.out.println("Inside action....");
      return "success";
   }  

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

Đây là cùng một lớp mà chúng ta đã thấy trong các ví dụ trước. Chúng tôi có các phương thức getters và setter tiêu chuẩn cho thuộc tính "name" và một phương thức thực thi trả về chuỗi "thành công".

Tạo chế độ xem

Hãy để chúng tôi tạo tệp jsp dưới đây HelloWorld.jsp trong thư mục WebContent trong dự án nhật thực của bạn.

<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      Hello World, <s:property value = "name"/>
   </body>
</html>

Tạo trang chính

Chúng tôi cũng cần tạo index.jsptrong thư mục WebContent. Tệp này sẽ đóng vai trò là URL hành động ban đầu, nơi người dùng có thể nhấp vào để yêu cầu khung Struts 2 gọi phương thức đã xác định của lớp HelloWorldAction và hiển thị dạng xem HelloWorld.jsp.

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>Hello World</title>
   </head>
   
   <body>
      <h1>Hello World From Struts2</h1>
      <form action = "hello">
         <label for = "name">Please enter your name</label><br/>
         <input type = "text" name = "name"/>
         <input type = "submit" value = "Say Hello"/>
      </form>
   </body>
</html>

Các hello hành động được xác định trong tệp dạng xem trên sẽ được ánh xạ tới lớp HelloWorldAction và phương thức thực thi của nó bằng tệp struts.xml.

Tệp cấu hình

Bây giờ, chúng ta cần đăng ký bộ đánh chặn của mình và sau đó gọi nó như chúng ta đã gọi bộ đánh chặn mặc định trong ví dụ trước. Để đăng ký một trình đánh chặn mới được xác định, các thẻ <interceptors> ... </interceptors> được đặt ngay dưới thẻ <package> instruts.xmltập tin. Bạn có thể bỏ qua bước này đối với bộ đánh chặn mặc định như chúng ta đã làm trong ví dụ trước. Nhưng ở đây chúng ta hãy đăng ký và sử dụng nó như sau:

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">

      <interceptors>
         <interceptor name = "myinterceptor"
            class = "com.tutorialspoint.struts2.MyInterceptor" />
      </interceptors>

      <action name = "hello" 
         class = "com.tutorialspoint.struts2.HelloWorldAction" 
         method = "execute">
         <interceptor-ref name = "params"/>
         <interceptor-ref name = "myinterceptor" />
         <result name = "success">/HelloWorld.jsp</result>
      </action>

   </package>
</struts>

Cần lưu ý rằng bạn có thể đăng ký nhiều hơn một bộ đánh chặn bên trong <package> và đồng thời, bạn có thể gọi nhiều hơn một bộ chặn bên trong <action>nhãn. Bạn có thể gọi cùng một máy đánh chặn với các hành động khác nhau.

Tệp web.xml cần được tạo trong thư mục WEB-INF trong WebContent như sau:

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee" 
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">
   
   <display-name>Struts 2</display-name>
   
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

Nhấp chuột phải vào tên dự án và nhấp vào Export > WAR Fileđể tạo tệp Chiến tranh. Sau đó, triển khai WAR này trong thư mục ứng dụng web của Tomcat. Cuối cùng, khởi động máy chủ Tomcat và cố gắng truy cập URLhttp://localhost:8080/HelloWorldStruts2/index.jsp. Điều này sẽ tạo ra màn hình sau:

Bây giờ nhập bất kỳ từ nào vào hộp văn bản đã cho và nhấp vào nút Nói Xin chào để thực hiện hành động đã xác định. Bây giờ nếu bạn kiểm tra nhật ký đã tạo, bạn sẽ tìm thấy văn bản sau ở dưới cùng:

Pre-Processing
Inside action....
Post-Processing

Xếp chồng nhiều thiết bị đánh chặn

Như bạn có thể tưởng tượng, việc phải cấu hình nhiều thiết bị đánh chặn cho mỗi hành động sẽ nhanh chóng trở nên cực kỳ khó quản lý. Vì lý do này, các thiết bị đánh chặn được quản lý bằng các ngăn xếp đánh chặn. Đây là một ví dụ, trực tiếp từ tệp strutsdefault.xml -

<interceptor-stack name = "basicStack">
   <interceptor-ref name = "exception"/>
   <interceptor-ref name = "servlet-config"/>
   <interceptor-ref name = "prepare"/>
   <interceptor-ref name = "checkbox"/>
   <interceptor-ref name = "params"/>
   <interceptor-ref name = "conversionError"/>
</interceptor-stack>

Số tiền trên được gọi là basicStackvà có thể được sử dụng trong cấu hình của bạn như hình dưới đây. Nút cấu hình này được đặt dưới nút <package ... />. Mỗi thẻ <interceptor-ref ... /> tham chiếu đến một bộ đánh chặn hoặc một ngăn xếp đánh chặn đã được cấu hình trước ngăn xếp đánh chặn hiện tại. Do đó, điều rất quan trọng là phải đảm bảo rằng tên là duy nhất trên tất cả các cấu hình bộ đánh chặn và bộ đánh chặn khi định cấu hình bộ đánh chặn và ngăn xếp bộ đánh chặn ban đầu.

Chúng ta đã thấy cách áp dụng hệ thống đánh chặn vào hành động, việc áp dụng các ngăn xếp đánh chặn cũng không khác gì. Trên thực tế, chúng tôi sử dụng chính xác cùng một thẻ -

<action name = "hello" class = "com.tutorialspoint.struts2.MyAction">
   <interceptor-ref name = "basicStack"/>
   <result>view.jsp</result>
</action

Việc đăng ký "basicStack" ở trên sẽ đăng ký cổ phần hoàn chỉnh của tất cả sáu bộ đánh chặn với hành động chào. Điều này cần lưu ý rằng các bộ đánh chặn được thực hiện theo thứ tự mà chúng đã được cấu hình. Ví dụ, trong trường hợp trên, ngoại lệ sẽ được thực thi đầu tiên, thứ hai sẽ là servlet-config, v.v.