SSH Development Model - Struts 2 (Section 3)

Struts 2 framework knowledge points, although divided into several sections, feel that the content is still quite a lot, but you are only introductory, to further improve yourself, you have to have a persistent learning heart, the final content I will talk about in this blog, so the length may be a bit long, I hope you can. Read with patience.

Firstly, the configuration of struts 2 is introduced.
Remember the test.jsp file we created? The students who read this blog directly need not read my previous blog, because I simply introduced the use of the previous blog, but did not go into depth, I did not explain the role of each step, and why to write like this. Therefore, it is also possible to start reading and learning directly from this blog. I will start with the most basic configuration and explain the role and reasons of each step.

So the code in the test.jsp file is very simple, it's 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' starting page</title>
    </head>
  <body>
       The Way to Get Into:<br>  
      <a href="${pageContext.request.contextPath}/primer/helloWorldAction.action">helloWorld</a><br>
  </body>
</html>

Let's introduce the path settings for accessing the Hello world application.
In struts 2, the URL path to access action s in struts 2 consists of two parts:
Name of package namespace + action
For example, the URL path to access this example HelloWorldAction is: / primer / helloWorldAction. Action. (Note: The complete path is http://localhost: port/content path/primer/helloWorldAction.action.) In addition, we can add the. Action suffix to access this Action.

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

The action name in the path must correspond to the name attribute of the action tag that you configure under the package tag.

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

       test Action Search order of 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>
 
     No action action Appoint class<br>
        <a href="${pageContext.request.contextPath}/primer/actionNoClass.action">helloWorld</a><br>
       
      test struts2 Output has no namespace helloworld:<br>
        <a href="${pageContext.request.contextPath}/primer/userAction.action">helloWorld</a><br>

What happens if we click on these three request links?
If you try to click, you will find that all three request links can be processed and run correctly. Then we think, why can it work correctly without configuration? This is because in struts 2, when you click on the request link, it searches for Action. Take the first link as an example, <a href="${pageContext.request.contextPath}/primer/primer/primer/helloWorldAction.action"> helloWorld</a>, when you click on the link, you will search for/primer/primer/primer/helloWorldAction.action, when you can't find it, you will search for/primer/primer/helloWorldAction.action. Then, search / primer / helloWorldAction. action, and so on, until the action is found. So if I write this, <a href="${pageContext.request.contextPath}/primer/primer/aaa/helloWorldAction.action">helloWorld</a>, the program will report an error.

So if you don't configure the class attribute for the action tag, will the program have problems?
Add an action tag to the package tag.

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

When we run and click, we will find that the program is still running correctly. The problem is that I haven't even configured the class. How does it run to get the result success and jump the page?
We looked at the struts-default.xml file and saw the configuration of the last few lines.

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

Do you understand When no class is specified for action, the struts2 framework executes the action by default. When we looked up the source code of the ActionSupport class, we found a way.

public static final String SUCCESS = "success";

public String execute() throws Exception {
        return SUCCESS;
}

This method is familiar with it, so why can it work without configuring class attributes, I believe you already understand.

If the requested path lookup fails to find the action, the program will throw an exception, which can be configured to perform the default action when the action is not found.

<package name="primer"  namespace="/"  extends="struts-default">
     <!--Specify default action Quote,If there is no corresponding under the package action To configure,Enable this configuration-->
     <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>

Next, let's look at the ActionSupport class, which is the default Action that we didn't specify for class execution.
It's much more powerful than the Action interface, so when we write the Action class, we can inherit the ActionSupport class instead.

I believe that many students at the beginning of this. action suffix can not understand, why write. action? Let's get to know.
Struts PrepareAndExecute Filter is the core controller of Struts 2 framework. It is responsible for intercepting all user requests specified by /* and filtering user requests when user requests arrive. By default, if the user requests a path without suffix or suffix ends with. action, the request will be forwarded to the Struts 2 framework for processing, otherwise the Struts 2 framework will skip the processing of the request.

Constant decisions based on the definition of the org.apache.struts2/default.properties file under the struts2-core-2.1.8.1.jar package
struts.action.extension=action,,

The default processing suffix can be modified by the constant struts.action.extension. Struts 2 is configured as follows to handle only the request path suffixed by. do:

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

If the user needs to specify more than one request suffix, the suffixes are separated by English commas (,). Such as:

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

We also have a second way to modify suffixes.
Configure constants in struts.properties, (the struts.properties file is placed under src)
struts.action.extension=do.go
Since there are two ways, which configuration will it enable if I implement both? I won't sell. If you implement both approaches, the struts 2 framework will enable the configuration of struts.properties. So why is that? I can explain it to you.
Because constants can be defined in multiple configuration files, we need to understand the search order of struts2 loading 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 constants configured in the latter file override the constants configured in the previous file.
Popularly speaking, the later the file is executed, the higher the priority.
Although there are two ways to achieve this, we do not recommend that you use the second way to create your own configuration files.

Then there is the usual introduction of constants.
Specify the default encoding set that acts on the setCharacter Encoding method of HttpServletRequest and the output of freemarker and velocity

This property specifies the request suffix that needs to be processed by Struts 2. The default value of this property is action, that is, all requests matching *. action are processed by Struts 2.
If the user needs to specify more than one request suffix, the suffixes are separated by English commas (,)

Set whether the browser caches static content, the default value is true (used in production environment), the development phase is best closed

Configuration When an internationalized file is modified, reload the internationalized resource file. The default value is false (no reloading), and true is reloaded.

When the configuration file of struts is modified, does the system automatically reload the file, the default value is false (no reloading), and true is reloaded?

Use in development mode, so that more detailed error messages can be printed out. The default value is false (used in production environment). It is best to open the development phase.

Default View Theme

When integrating with spring, specify that spring is responsible for the creation of action objects

This property sets whether Struts 2 supports dynamic method calls, and the default value of this property is true. If you need to turn off dynamic method calls, you can set this property
For false

Size limitation of uploaded files

Next comes the second part, the result type of struts 2.
We create a new folder resulttype, and then 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="Submission">
    </form>
  </body>
</html>

Then we create the corresponding action, this time we don't implement the Action interface, but inherit the ActionSupport class.

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

Configure it and add it to 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>

The success.jsp page to turn to is as follows

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

Click on the submit button and the page successfully displays the data stored in the request range. What does that mean? It shows that my way of turning must be forwarding, if it is redirected, the data will not be available. In fact, there is a type attribute in the result tag that can be used to set the steering mode, except that it defaults to "dispatcher".
This is the first way to set the steering, and we also have the second way.

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

This configuration of the result tag also enables steering. This location refers to the page to be forwarded to. The implementation principle of this method can also be found in struts-default.xml file. I will not show you, interested students can study it by themselves. Knowing about forwarding, how does redirection work? This is too simple. Change the type value to "redirect".
Note that in redirection, you need to switch to jsp to write like this, and if you want to move to action, you need to configure like this:

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

The last part is struts2 wildcards and dynamic method calls.
Before we say this, we should expand a knowledge point.
Let's first create 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">Submission</a>
</body>
</html>

There is only one hyperlink in it, and then configure the struts.xml file. I believe that the configuration is difficult for you, 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>

Then create the BookAction.java file.

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

We run the project, then click Submit, and the page will turn to the success.jsp file. What if I want to click the page and jump to the bookaction.jsp file we configured? In fact, it is very simple to have a method attribute in the action tag, just set its value to the method name. Is this custom method easy to write? Of course not. It must be modified by the public keyword, must have a return value, this method can not pass parameters, in summary, except the method name and execute method, the other must be the same as it. Someone here will say, you have a problem with this statement. The execute method throws exceptions, but the custom method does not. I will explain that this is because the test code we write is too simple to handle exceptions, so you can not throw exceptions, but when the code is very complex, the process. There will be more or less exceptions to the order, and then the exception must be thrown.

That's the first part. Let's go back to our focus, wildcards.
We added three hyperlinks to the test.jsp file.

    Sample wildcard mapping(1):<br>
    <a href="${pageContext.request.contextPath}/a_add.action"> Sample wildcard mapping(1)</a><br>
    <a href="${pageContext.request.contextPath}/b_add.action"> Sample wildcard mapping(1)</a><br>
    <a href="${pageContext.request.contextPath}/c_add.action"> Sample wildcard mapping(1)</a><br>
    <br> 
    <br>
    <br>

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>

Running the program, the program is running normally, but this configuration is obviously troublesome, is there any simple way to write it? At this point wildcards come in handy, we delete all previous configurations, and then write the following configurations.

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

There is no problem running the project. This number is a wildcard. Some students who are basic in language should understand it. I won't say much about it.
The knowledge points of struts2 wildcards are given below.
A Web application may have hundreds of action declarations. The wildcard mapping mechanism provided by struts can be used to simplify many similar mapping relationships into one mapping relationship.
Wildcard mapping rules
If multiple matches are found, the one without wildcards wins.
If the specified action does not exist, Struts will attempt to match the URI with any action name containing wildcards.
If Struts finds more than one match with wildcards, the last match wins.
The substrings of URI strings matched by wildcards can be referenced by {1}, {2}. {1} matches the first substring, {2} matches the second substring. {0} matches the entire URI

  • You can match zero or more characters, but not / characters. If you want to include / characters, you need to use **. If you need to escape a character, you need to use **.

Finally, the dynamic method call.
Dynamic method invocation: invoking methods in Action dynamically through url
If there are more than one method in Action, we can call the specified method with! + method name
By default, Struts dynamic method calls are active. To disable this feature, you can add the following constant elements in the struts.xml file:

As an example of the above project, I can no longer configure the method in action, but make the following changes in the url address of the hyperlink:

<a href="${pageContext.request.contextPath }/bookAction!add.action">Submission</a>

So I can also call the add method in the configuration action after clicking the submit button. This is the dynamic method call.

At this point, the learning of struts 2 framework is over. Of course, the knowledge of struts 2 framework is much more than that. Interested students can continue to study in depth. I'll finish here first.

Tags: Java Struts JSP xml

Posted on Sun, 25 Aug 2019 23:31:41 -0700 by tomhath