This is the 19th day of my participation in the August Wenwen Challenge.More challenges in August

Let’s start with struts2 configuration. Remember the test.jsp file we created? Those of you who read this directly don’t have to read my previous blog, because in my previous blog, I just briefly introduced the use of it, but I didn’t go into the details. I didn’t explain what each step does and why I wrote it this way. So, it’s ok to start with this blog post, and I’ll start with the basics and explain what each step does and why.

The code in the test.jsp file is simply a hyperlink.

<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags"   prefix="s"%>
<html>
  <head>
    <title>My JSP 'index.jsp'<br> <a href="${pageContext.request.contextPath}/primer/helloWorldAction.action">helloWorld</a><br>
  </body>
</html>
Copy the code

Let’s talk about setting the path to the helloWorld application. In Struts2, the URL path to the action in Struts2 consists of two parts: the package namespace + the action name for example: Access this example HelloWorldAction URL path is: / primer/HelloWorldAction. Action (note: the full path is: http://localhost: port/contents/primer/helloWorldAction path. The action). Alternatively, we can access the action by adding the. Action suffix.

 <package name="primer" namespace="/ primer"   extends="struts-default">
      <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
        <result name="success" type="dispatcher">/success.jsp</result>
      </action>
 </package>
Copy the code

The action name in the path must match the name property of the action tag that you configured under the Package tag.

Next we add the following code to the test.jsp file.

Test the search order of Action names :<br> <a href="${pageContext.request.contextPath}/primer/primer/primer/helloWorldAction.action">helloWorld</a><br>
        <a href="${pageContext.request.contextPath}/primer/primer/helloWorldAction.action">helloWorld</a><br>
        <a href="${pageContext.request.contextPath}/primer/helloWorldAction.action">helloWorld</a><br> Not specified for actionclass<br>
        <a href="${pageContext.request.contextPath}/primer/actionNoClass.action">helloWorld</a><br> Tests struts2 output with no namespace helloWorld :<br> <a href="${pageContext.request.contextPath}/primer/userAction.action">helloWorld</a><br>
Copy the code

What happens if we click on the three request links? If you try clicking on it, you’ll see that all three request links are handled correctly. So we thought, why does it work without configuration? This is because in Struts2, when you click on the request link, it does a search for the Action. In the first link, for example, < a href = “${pageContext. Request. ContextPath} / primer/primer/primer/helloWorldAction action” > helloWorld < / a >, When you click the link to search/primer/primer, primer/helloWorldAction action, when the query is less than, can search/primer/primer/helloWorldAction. Action, the query is less than, Will search/primer/helloWorldAction. Action, and so on, until the action is found. So if I write so, < a href = “${pageContext. Request. ContextPath} / primer/primer/aaa/helloWorldAction action” > helloWorld < / a >, the program will be an error.

Does the application have a problem if the class attribute is not configured for the action tag? Add an Action tag to the Package tag.

<action name="actionNoClass">
		<result name="success">/primer/success.jsp</result>
</action>
Copy the code

If you run it and click on it, you will find that the program is still running correctly. So, how does it run to get success and jump to the page? We look at the struts-default.xml file and see the last few lines of configuration

 <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
Copy the code

Do you understand? The Struts2 framework executes the action by default when no class is specified for the action. When we looked at the ActionSupport class source code, we found a method.

public static final String SUCCESS = "success";

public String execute(a) throws Exception {
        return SUCCESS;
}
Copy the code

This method is pretty familiar, so you can see why it works without the class attribute configured.

If the action cannot be found in the requested path, the program will throw an exception. You can configure the default action to be executed if the action cannot be found

<package name="primer"  namespace="/"  extends="struts-default">
     <! -- Specify the default action reference, and enable it if there is no action configuration in the package -->
     <default-action-ref name="helloWorldAction"></default-action-ref>

     <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <result name="success" type="dispatcher">/success.jsp</result>
      </action>
     <action name="actionNoClass">
          <result>/success.jsp</result>
     </action>
 </package>
Copy the code

Next, let’s look at the ActionSupport class, which is the default Action that we execute without specifying a class. It is far more powerful than the Action interface, so we can write Action classes that inherit from ActionSupport classes instead.

I believe that many students at the beginning of the. Action suffix expressed that they could not understand, why write. Action? Let’s see. StrutsPrepareAndExecuteFilter is the core of the Struts 2 framework controller, which is responsible for intercept designated by / * all user requests, when the user requests arrived, the Filter will Filter the user’s request. By default, if a user requests a path with no suffix or a suffix ending in. Action, the request is forwarded to The Struts 2 framework for processing, otherwise it is skipped.

According to the configuration file: struts 2 – core – 2.1.8.1. Org. Under the jars. Apache struts 2 / default. The properties file defines the constant decided to struts. The action. The extension = action,

The default processing suffix can be modified by using the constant “struts.action.extension”, for example, struts 2 is configured to handle only request paths with a. Do suffix:

<struts>
    <constant name="struts.action.extension" value="do"/>
</struts>
Copy the code

If the user needs to specify multiple request suffixes, they are separated by commas (,). Such as:

 <constant name="struts.action.extension" value="do,go"/>
Copy the code

There is a second way to modify suffixes. Struts.properties file is placed under SRC. Struts.action.extension =do.go Since there are two ways, if I implement both ways, which configuration will it enable? I won’t keep you in suspense, but if you implement both, the Struts2 framework will enable the struts.properties configuration. So why is that? I can explain it to you. Since constants can be defined in multiple configuration files, we need to understand the search order in which Struts2 loaded constants: 1 struts-default. XML 2 struts-plugin. XML 3 struts. XML 4 struts.properties(created by yourself) 5 Web.xml If the same constant is configured in multiple files, The constant value configured in the later file overwrites the constant value configured in the previous file. In layman’s terms, files executed later have higher priorities. There are two ways to do this, but the second way to create your own configuration file is not recommended.

Then there is an introduction to commonly used constants. This attribute specifies the request suffix that needs to be processed by Struts 2. The default value of this attribute is action, That is, all requests matching *. Action are processed by Struts2. If the user needs to specify multiple request suffixes, Set whether the browser caches static content. The default value is true(used in the production environment). Close the configuration during the development phase When the Struts configuration file is modified, the system automatically reloads the file. The default value is false(not reloading), and true is used in development mode to print more detailed error information. The default value is false(for production) Specifies that Spring is responsible for the creation of action objects when integrated with Spring. This property sets whether Dynamic method calls are supported by Struts 2 and defaults to true. <constant name=”struts.multipart.maxSize” value= “10701096”/>

Next comes the second part, the struts2 result types. We create a new folder resultType and create the form.jsp file

<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags"   prefix="s"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    </head>
  <body>
    <form action="${pageContext.request.contextPath}/resulttype/resulttypeAction.action" 
          name="form1"  method="post">
      <input type="submit" value="Submit">
    </form>
  </body>
</html>
Copy the code

Then we create the corresponding Action. Instead of implementing the Action interface, we inherit the ActionSupport class.

public class ResultTypeAction extends ActionSupport {
	@Override
	public String execute(a) throws Exception {
		System.out.println("ResultTypeAction ...");
		
		HttpServletRequest request = ServletActionContext.getRequest();
		request.setAttribute("username"."username_request");
		
		return "success"; }}Copy the code

Configure it and add it in the struts.xml file

<package name="resulttype" namespace="/resulttype" extends="struts-default">
		<action name="resulttypeAction" class="cn.itcast.action.ResultTypeAction">
			<result name="success">/resulttype/success.jsp</result>
		</action>
</package>
Copy the code

The success. JSP page to turn to is shown below

<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/struts-tags"   prefix="s"%>
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    </head>
  <body>
            resulttype :   ${requestScope.username}
  </body>
</html>
Copy the code

Click the submit button and the page successfully displays the data saved in the request scope. What does that tell you? That means my way of turning must be forward, if it is redirected then the data can not be obtained. In fact, there is a type attribute in the result tag that can be used to set the direction, but it defaults to “dispatcher”. That’s the first way to set up steering, and we have a second way.

<result name="success" type="dispatcher">
		<param name="location">/resulttype/success.jsp</param>
</result>
Copy the code

The result tag can also be configured to redirect. This location refers to the page to be forwarded to. The implementation principle of this method can also be found in the struts-default. XML file, I will not show you, interested students can study for themselves. Knowing forwarding, how does redirection work? This is too simple. Just change the type value to “redirect”. Note that in redirection, you can only write this if you go to JSP, but if you want to go to Action, you need to configure it like this:

<result name="success" type="redirectAction">
	<param name="actionName">helloWorldAction</param>
	<param name="namespace">/primer</param>
</result>
Copy the code

The last part is struts2 wildcards and dynamic method calls. Before WE get to that, let’s expand on one point. Let’s start with a new test.jsp file.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"% > <! DOCTYPE html PUBLIC"- / / / / W3C DTD HTML 4.01 Transitional / / EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="${pageContext.request.contextPath }/bookAction.action"> Submit </a> </body> </ HTML >Copy the code

The struts. XML file is configured with only one hyperlink, so I will configure the action as follows.

<action name="bookAction" class="cn.itcast.action.BookAction">
	<result name="success">/success.jsp</result>
	<result name="add">/bookaction.jsp</result>
</action>
Copy the code

Then create the bookAction.java file.

public class BookAction extends ActionSupport{
	@Override
	public String execute(a) throws Exception {
		System.out.println("BookAction ...");
		return "success";
	}
	
	public String add(a){
		System.out.println("add ...");
		return "add"; }}Copy the code

We run the project, then click Submit, and the page goes to the success.jsp file, so what if I want to click on the page to jump to the bookAction.jsp file that we configured? In fact, there is a method attribute in the Action tag, just set its value to the method name. Can this custom method be written anywhere? Of course not. It must be decorated with the public keyword, it must return a value, it cannot pass arguments, and it must be the same as the execute method except for its name. Here someone will say, you this sentence has a problem, the execute method throws exceptions, and the methods of the custom not throw, I explain, it is because we write the test code is too simple, so that there are no exceptions to process, so you can not throw exceptions, but when the code is very complex, program more or less there will be exceptions, This is when you must throw an exception.

That’s it for now, but let’s get back to the wildcard. We add three hyperlinks to the test.jsp file.

Wildcard mapping example (1):<br>
    <a href="${pageContext.request.contextPath}/a_add.action"> Wildcard mapping example (1)</a><br>
    <a href="${pageContext.request.contextPath}/b_add.action"> Wildcard mapping example (1)</a><br>
    <a href="${pageContext.request.contextPath}/c_add.action"> Wildcard mapping example (1)</a><br>
    <br> 
    <br>
    <br>
Copy the code

Then configure struts.xml.

<action name="a_add" class="cn.itcast.action.BookAction" method="add">
	<result name="success">/success.jsp</result>
	<result name="add">/bookaction.jsp</result>
</action>
<action name="b_add" class="cn.itcast.action.BookAction" method="add">
	<result name="success">/success.jsp</result>
	<result name="add">/bookaction.jsp</result>
</action>
<action name="c_add" class="cn.itcast.action.BookAction" method="add">
	<result name="success">/success.jsp</result>
	<result name="add">/bookaction.jsp</result>
</action>
Copy the code

Run the program, the program runs normally, but this configuration is obviously very troublesome, what is a little simpler writing? This is where wildcards come in. Let’s delete the previous configuration and write the following configuration.

<action name="*_add" class="cn.itcast.action.BookAction" method="add">
	<result name="success">/success.jsp</result>
	<result name="add">/bookaction.jsp</result>
</action>
Copy the code

There is no problem running the project. This * is the wildcard, some of the language foundation students should understand, I will not say more. Struts2 wildcard: struts2 wildcard A Web application may have hundreds or thousands of action declarations. The wildcard mapping mechanism provided by Struts can be used to simplify multiple mapping relationships that are similar to each other into a single mapping relationship. Wildcard mapping rule If multiple matches are found, the one without the wildcard will win. Struts will attempt to match this URI with any action name containing the wildcard *. If Struts finds more than one match with the wildcard, the last match will win. {1} matches the first substring, {2} matches the second… {0} matches the entire URI

  • Can match zero or more characters, but not the/character. If you want to include the/character, use **. If you want to escape a character, use \.

Finally, dynamic method calls. Dynamic method invocation: call a method in an Action dynamically from a URL. Struts dynamic method calls are enabled by default. If you want to disable this feature, you can add the following constant element to the Struts. XML file: For example, instead of using method in the action, I could change the url of the hyperlink as follows:

<a href="${pageContext.request.contextPath }/bookAction! add.action"> submit < / a >Copy the code

This way I can also call the Add method in the configuration Action after CLICKING the Submit button. This is dynamic method invocation.