Introduction and Introduction to [Struts2]

Posted by t.bo on Sat, 09 Nov 2019 21:49:32 +0100

1. Overview

  1. Question: What is a framework and what is it useful for?
    • Framework is the code (semi-finished product) that implements part of the function. It is used to simplify enterprise software development and improve development efficiency.
    • Learning Framework, to be clear about what the knowledge framework can do and what else needs to be coded
  2. Question: What is the Struts2 framework and what is its use?
    • Struts 2 is the next generation product of Struts, a brand new Struts 2 framework that is based on the technology of Struts 1 and WebWork.Its new Struts2 architecture is very different from that of Struts1.Struts2 takes WebWork as its core, Struts2=Struts1+Webwork
    • The Struts2 framework is an Apache product.
    • Struts2 is a standard MVC framework.
    • Model2 mode in Java Web is an mvc mode
    • Model2=Servlet+Jsp+JavaBean
    • The Struts2 framework is used in Java web development.
    • Using the Struts2 framework, we can simplify our web development and reduce program coupling.
  3. Products similar to the struts2 framework:
    • Struts1 Webwork Jsf Springmvc
    • SSH --- Struts2 + Spring + Hibernate
    • SSM --- SpringMVC + Spring + Mbatis
  4. XWork - it's the core of WebWork
    • Xwork provides many core functions: interceptor, runtime form attribute validation, type conversion, powerful expression language (OGNL - the Object Graph Navigation Language), IoC (Inversion of Control Inversion) container, and so on.

2. Struts2 Quick Start Program

2.1 Development Process Comparison

  • Web development process: index.jsp------> HelloServlet--------> hello.jsp
  • Struts2 process: index.jsp------>HelloAction--------->hello.jsp

2.2 Introducing dependencies

<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.3.16.3</version>
</dependency>

2.2 Create a jsp page

  • Create index.jsp page (later modified)
  • Create a hello.jsp page (as follows)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
    <h1>hello Struts2</h1>
  </body>
</html>

2.3 Configuring a front-end controller in web.xml

  • Configuring a front-end controller (core controller) in the web.xml file -- is a Filter
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2.4 Create struts.xml configuration file

  • Create a struts.xml configuration file under src (classes), which is the struts2 framework configuration file.

2.4 Create a HelloAction class

  • Requires that a return value be created in the HelloAction class as a String type method, note that there are no parameters.
public class HelloAction {
    
    public String say() {
        return "good";
    }
}

2.5 Configuring HelloAction in the struts.xml file

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

<struts>

    <package name="default" namespace="/" extends="struts-default">
        <action name="hello" class="com.hao.action.HelloAction"
            method="say">
            <result name="good">/hello.jsp</result>
        </action>
    </package>
    
</struts>

2.6 Add connections in index.jsp, test

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  <body>
    <a href="${pageContext.request.contextPath}/hello">First use struts2</a>
  </body>
</html>

2.7 Test

  • Enter: http://localhost:8080/Struts2-001-EntryP/index.jsp to access the connection in the address bar, and you will see that the say method in the HelloAction class executed and jumped to hello.jsp.

3. Process analysis of entry procedure

  • Complete the starter program by mimicking the struts2 process:

3.1 Create projects to introduce Maven dependencies

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.3.16.3</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>3.0-alpha-1</version>
    <scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>

3.2 Custom StrusFilter Filter

  • 1. Create a Filter--StrutsFilter
  • 2. Configure StrutsFilter in the web.xml file
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <filter>
    <filter-name>StrutsFilter</filter-name>
    <display-name>StrutsFilter</display-name>
    <description></description>
    <filter-class>com.hao.filter.StrutsFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>StrutsFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
  • 3. Complete the intercept operation in StrutsFilter, access the methods in Action, and jump to the hello.jsp page operation.
public class StrutsFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        // 1. Turn Strong
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        // 2. Operation

        // 2.1 Get Request Resource Path
        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();
        String path = uri.substring(contextPath.length() + 1);

        // System.out.println(path); // hello

        // 2.2 Use path to find a <action name=path>tag in the struts.xml file
        SAXReader reader = new SAXReader();

        try {
            // Gets the document object of the struts.xml file.
            Document document = reader.read(new File(this.getClass().getResource("/struts.xml").getPath()));

            Element actionElement = (Element) document.selectSingleNode("//Action [@name=''+ + path +']';//find <action
                                                                                                            // Label such as name='hello'>

            if (actionElement != null) {
                // Get the class attribute and method attribute on the <action>tag
                String className = actionElement.attributeValue("class"); // Gets the name of the action class
                String methodName = actionElement.attributeValue("method");// Gets the method name in the action class.

                // 2.3 By reflection, we get a Class byte code object and a Method object
                Class<?> actionClass = Class.forName(className);
                Method method = actionClass.getDeclaredMethod(methodName);

                // Processing request parameter encapsulation:

                Object actionObj = actionClass.newInstance();

                // 2. Model Driven
                if (actionObj instanceof MyModelDriven) {
                    MyModelDriven mmd = (MyModelDriven) actionObj;

                    BeanUtils.populate(mmd.getModel(), request.getParameterMap());
                } else {
                    // 1. Attribute Driven
                    BeanUtils.populate(actionObj, request.getParameterMap());//
                }

                // 2.4 Let the method execute.
                String returnValue = (String) method.invoke(actionObj); // Is to have the method in the action class execute and get the return value of the method.

                // 2.5
                // Use returnValue to find the name attribute value of its child element result under action and compare it with returnValue.
                Element resultElement = actionElement.element("result");
                String nameValue = resultElement.attributeValue("name");

                if (returnValue.equals(nameValue)) {
                    // 2.6 Get the route to jump.
                    String skipPath = resultElement.getText();

                    // System.out.println(skipPath);

                    request.getRequestDispatcher(skipPath).forward(request, response);
                    return;
                }
            }

        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

        // 3. Release
        chain.doFilter(request, response);

    }

    public void destroy() {
    }

}

3.3 Process Analysis

  • Request ---- StrutsPrepareAndExecuteFilter Core Controller --- Interceptors Interceptors (Implementing Code Functions) --- Excute of Action --- Result of Result Page

4. Struts2 Configuration

4.1 Struts2 Profile Loading Order

  • To execute the Struts2 framework, you must first load the StrutsPrepareAndExecuteFilter.
  • Dispatcher is initialized in the init method of StrutsPrepareAndExecuteFilter.
  • The order in which struts2 configuration files are loaded is described within the init method defined in the Dispatcher class
// [1]   org/apache/struts2/default.properties 
init_DefaultProperties();
// [2]  struts-default.xml,struts-plugin.xml,struts.xml 
init_TraditionalXmlConfigurations(); 
// [3] - Custom struts.properties (comment in source code does not [4])
init_LegacyStrutsProperties(); 
// [5] ----- Custom Configuration Provision
init_CustomConfigurationProviders(); 
// [6] ----- web.xml 
init_FilterInitParameters() ; 
// [7] ---- Bean Loading 
init_AliasStandardObjects() ; 
1.default.properties file
    Role: Defines all constants in the struts2 framework
    Location: org/apache/struts2/default.properties, under the struts2-core.jar package
    
2.struts-default.xml
    Role: Configured beans, interceptor, results, etc.
    Location: core jar package in struts.
    
  struts-plugin.xml
    It is the configuration file for the plug-ins used in the struts2 framework.
  struts.xml              
    We make the configuration file used by struts2.
        
3. Customized struts.properties
    We can customize constants.
    
4.web.xml
    
In development, loading the configuration in the file after loading overrides the configuration in the file after loading.We usually have to remember the following order:
default.properties
struts-default.xml
struts.xml

4.2 Configuration of Action

  1. <package>action: is used to declare a package.Used to manage actions.Its common properties are as follows
    • Name: It is used to declare a package name that cannot be duplicated, that is, it is unique.
    • namespace: It combines with the name attribute of the action tag to determine a unique path to the action.
    • extends: It represents the inherited package name.
    • abstrace: It can take the value true/false, if true, to indicate that the package is used for inheritance.
  2. <action>is used to declare an action and its common properties are as follows:
    • Name: is the name of an action, which is unique (within the same package) and identifies the path to access the action with the namespace in the package.
    • Class: Full name of the Action class
    • Method: The name of the method in the Action class to access. The method has no parameters and the return value is String.
  3. <result>is used to determine the return result type, and its common properties are as follows:
    • NameIt compares with the method return value in the action to determine the jump path.

4.3 Additional details about action configuration:

  1. About Default Values
    • <package namespace="Default"> -- The default value of namespace is ""
    • <action class="default value" method="default value"> -- default value of class is "com.opensymphony.xwork2.ActionSupport", default value of method is execute
    • The default value for <result name="default value"> name is "success"
  2. Regarding the path to the action, the action is now configured to:

    <package name="default" namespace="/" extends="struts-default">
    <action name="hello" class="com.hao.action.DefaultAction">
    <result>/hello.jsp</result>
    </action>
    </package>
    • action is also accessible when we type: http://localhost/Struts2-003-ExerConfig/a/b/c/hello.
    • Reason: When an action in struts2 is accessed, it first looks for it
    • txt 1.namespace="/a/b/c" action name=hello does not exist.
      2.namespace="/a/b action name=hello does not
      3.namespace="/a" action name=hello does not
      4.namespace="/" action name=hello lookup found.
    • If it is not found at last, a 404 error will be reported.
  3. Default action.

    • Role: Handles paths that other action s cannot handle.
    • <default-action-ref name="name of action"/>, which is configured to execute an action with the name specified when the path accessed cannot be handled by other actions.
  4. Default processing class for action

    • If class is not written when action is configured.By default, it is com.opensymphony.xwork2.ActionSupport
    • <default-class-ref class="com.hao.action.DefaultAction"/>, if set, then under the current package, the default processing class for action requests is the class specified for class.

4.4 About Constant Configuration

  • default.properties It declares constants in struts.
  • Question: Where can I set constants artificially?

    • 1.struts.xml (most used), <constant name="constant name" value="constant value"></constant>
    • 2.struts.properties (rarely used)
    • 3.web.xml (Understanding), configuration constants are configured using the initialization parameters of the StrutsPrepareAndExecuteFilter.
    <init-param>
        <param-name>struts.action.extension</param-name>
    <param-value>do,,</param-value>
    </init-param>
  • Common Constants

    • struts.action.extension=action, --This constant is used to specify the suffix name that the strus2 framework intercepts by default.
    • <constant name="struts.i18n.encoding" value="UTF-8"/> -- equivalent to request.setCharacterEncoding("UTF-8"); resolves post request scrambling
    • <constant name="struts.serve.static.browserCache" value="false"/> -- false does not cache, true browser caches static content, production environment setting true, development environment setting false
    • <constant name="struts.devMode" value="true"/>, provide detailed error page, do not need to restart server after modifying struts.xml

Separation of the 3.5 struts.xml file:

  • Purpose: To facilitate reading.You can have a module with a configuration file and import other configuration files in the struts.xml file by <include file="test.xml"/>.

V. Action

5.1 How Action classes are created

  • Three ways to create

  1. Create a POJO class.
    • Simple Java Objects (Plain Old Java Objects)
    • Refers to the fact that no interface is implemented and no parent class is inherited (except Object)
    • Advantages: No coupling.
    • Disadvantages: All work needs to be done on your own.
    • At the bottom of the struts2 framework is reflected:
      • The struts2 framework reads struts.xml to get the full Action class name
      • obj = Class.forName("full class name"). newInstance();
      • Method m = Class.forName("full class name"). getMethod ("execute"); m.invoke (obj); execute method by reflection
  2. Create a class that implements the Action interface. (com.opensymphony.xwork2.Action)

    • Advantages: Low coupling.Five result views are provided and a behavior method is defined.
    • Disadvantages: All work needs to be done on your own.
    public static final String SUCCESS = "success";  // Data Processing Success (Success Page)
    public static final String NONE = "none";  // Page does not jump return null; the effect is the same
    public static final String ERROR = "error"; // Data processing send error (error page)
    public static final String INPUT = "input"; // User input data is incorrect and is often used for form data validation (input page)
    public static final String LOGIN = "login"; // Primary Rights Authentication (Landing Page)
  3. Create a class that inherits from the ActionSupport class. (com.opensymphony.xwork2.ActionSupport)

    • The ActionSupport class implements the Action interface.
    • Advantages: Form validation, error information settings, and reading international information are all supported.
    • Disadvantages: high coupling.
    • The third will be used more in development.

5.2 Access to action s

  • 1. Determine which method in the action class to access by setting the value of the method.
    • <action name="book_add" class="com.hao.action.BookAction" method="add"></action>
    • When book_add is accessed, the add method in the BookAction class is called.
    • <action name="book_update" class="com.hao.action.BookAction" method="update"></action>
    • When book_update is accessed, the update method in the BookAction class is called.
  • 2. Use wildcards to simplify configuration

    • Configuring in the struts.xml file
    • <action name="*_*" class="com.hao.action.{1}Action" method="{2}"></action>
    • jsp page
    • book.jsp
    <a href="${pageContext.request.contextPath}/Book_add">book add</a><br>
    <a href="${pageContext.request.contextPath}/Book_update">book update</a><br>
    <a href="${pageContext.request.contextPath}/Book_delete">book delete</a><br>
    <a href="${pageContext.request.contextPath}/Book_search">book search</a><br>
    • product.jsp
    <a href="${pageContext.request.contextPath}/Product_add">product add</a><br>
    <a href="${pageContext.request.contextPath}/Product_update">product update</a><br>
    <a href="${pageContext.request.contextPath}/Product_delete">product delete</a><br>
    <a href="${pageContext.request.contextPath}/Product_search">product search</a><br>
    • When accessing book add, the path is Book_add, so for struts.xml files.
    • The first * is Book
    • The second *is add
    • For {1}Action--> BookAction
    • For method={2}--->method=add
    • Use wildcards to configure considerations:
    • 1. A uniform naming convention must be defined.
    • 2. It is not recommended to use too many wildcards, which makes reading inconvenient.
  • 3. Dynamic Method Calls (Understanding)

    • In the struts.xml file
    • <action name="book" class="com.hao.action.BookAction"></action> Access Path: http://localhost/Struts2-003-ExerConfig/book!
      You access the add method in the BookAction class.
    • For book!add this is a dynamic method call.
    • Note: The struts2 framework supports dynamic method calls because they are set in the default.properties configuration file and the dynamic method calls are true. struts.enable.DynamicMethodInvocation = true

5.3 Getting servlet api in struts2 framework

  • For struts2 framework, direct use of servlet api is not recommended;
  • There are three ways to obtain a servlet api in struts2:

  • 1. Get it through ActionContext

    • Gets an ActionContext object. ActionContext context=ActionContext.getContext()
    • Get servlet api
    • Note: ActionContext is not a real Servlet api, but a Map collection.
    1.context.getApplication()
    2.context.getSession()
    3.context.getParameter(); - - what you get is equivalent to request.getParameterMap()
    4.context.put(String,Object) is equivalent to request.setAttribute(String,String);
  • 2. Injection acquisition (this is really acquiring the servlet api)

    • The action class is required to implement the proposed interface.
    • ServletContextAware: Inject ServletContext object
    • ServletRequestAware: Inject request object
    • ServletResponseAware: Inject response object

    • Overrides methods in interfaces.

    • Declare a web object and assign values to the declared web object using the parameters of the methods in the interface.

    //Get the servlet api by injection
    public class ServletDemo2Action extends ActionSupport implements
    ServletRequestAware {
    private HttpServletRequest request;
    @Override
    public String execute() throws Exception {
    System.out.println(request.getParameter("username"));
    return null;
    }
    public void setServletRequest(HttpServletRequest request) {
    this.request = request;
    }
    }
    • Extension: Analyze its implementation using an interceptor in struts 2. (Interceptor in struts-default.xml)
    <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
    
         if (action instanceof ServletRequestAware) { //Determine if action implements the ServletRequestAware interface
            HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST); //Get the request object.
    ((ServletRequestAware) action).setServletRequest(request);//Inject the request object through a method overridden in the action.
    }
  • 3. Get it through ServletActionContext. The methods in ServletActionContext are static.

//Get servlet api via ServletActionContext
public class ServletDemo3Action extends ActionSupport {

    @Override
    public String execute() throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();

        System.out.println(request.getParameter("username"));
        return SUCCESS;
    }

}

5.4 Result result type

  • Label
  • 1.name matches the return value of the method in the action to jump.
  • 2. Typee function: Used to define jump modes
  • For the type attribute, its values are as follows:Define the acceptable values for the type in the struts-default.xml file
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
  • Will: chain dispatcher redirect redirect action stream
  • dispatcher: This represents request forwarding and is also the default value.It is typically used to jump from an action to a page.
  • chain: It is also equivalent to request forwarding.It is typically used to jump from one action to another.
  • redirect: It represents redirection It is typically used to jump from action to page
  • redirectAction: It represents a redirect that is typically used to jump from an action to another action.
  • Stream: Represents a stream returned by the server, typically for download.

  • Local and global results pages

<package name="default" namespace="/" extends="struts-default">
    <!-- Global Results Page -->
    <global-results>
        <result>/demo1_success.jsp</result>
    </global-results>

    <action name="demo1" class="com.hao.action.ServletDemo1Action">
        <!-- Local Results Page -->
    </action>

    <action name="demo2" class="com.hao.action.ServletDemo2Action">
        <!-- <result>/demo1_success.jsp</result> -->
    </action>

    <action name="demo3" class="com.hao.action.ServletDemo3Action">
        <!-- <result type="redirect">/demo1_success.jsp</result> -->
    </action>

</package>

Topics: Java Struts xml JSP Apache