JSP(第八章:Struts2)

1 第一个Struts2页面

2 配置文件

3 Action

4 校验机制

Struts官方网站:https://struts.apache.org/

入门资源:W3Cschool Strtus2

1 第一个Struts2页面

1.1 简单例子1

【导入jar包】:

【WebContent/WEB-INF/web.xml】:struts2实质就是过滤器实现

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>JSPStruts2</display-name>
  <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>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

【src/struts.xml】:

<?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>
<package name="mypack" namespace="/test" extends="struts-default">
<action name="helloworld" class="my.example.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
</package>
</struts>

【src/my.example/HelloWorldAction.java】:

package my.example;

public class HelloWorldAction {

    private String message;
       public String getMessage() {
        return message;
    }

    public String execute(){
           message="my first page";
           return "success";
       }
}

【运行结果】:启动服务器,访问地址:http://localhost:8080/JSPStruts2/test/helloworld

显示: my first page

这里 JSPStruts2 **是项目名,test**是struts.xml配置中package中的namespace。

1.2 简单例子2

【src/my.example/UserAction.java】:

package my.example;

public class UserAction { 

    private String username; 
    private String password; 

    public String getUsername() { 
        return username; 
    } 

    public void setUsername(String username) { 
        this.username = username; 
    } 

    public String getPassword() { 
        return password; 
    } 

    public void setPassword(String password) { 
        this.password = password; 
    } 

    public String execute() throws Exception { 
    // 只有用户名为root,密码为root方可成功登陆 
        if (username.equals("root") && password.equals("root")) { 
            return "success"; }
        else { 
            return "error"; 
        } 
    } 
}

【src/struts.xml】:

<struts>
<package name="mylogin" extends="struts-default"> 
    <action name="loginUser" class="my.example.UserAction">
    <result name="success">/success.jsp</result>
    <result name="error">/error.jsp</result>
</action>
</package>
</struts>

【WebContent/login.jsp】

<%@ taglib prefix="s" uri="/struts-tags" %> 
<!-- s:stuts标签 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="loginUser"> 
    <s:textfield name="username" label="用户名"></s:textfield> 
    <s:password name="password" label="密码"></s:password> 
    <s:submit value="确定"/><s:reset value="重置"/> 
</s:form> 
</body>
</html>

【WebContent/success.jsp】

<%@ taglib prefix="s" uri="/struts-tags" %> 
<body>
登陆成功!!!您的用户名是<s:property value="username"></s:property>
</body>

【WebContent/error.jsp】

 error!!!<br>

浏览器运行 http://localhost:8080/JSPStruts2/login.jsp

2 配置文件

2.1 web.xml文件

struts2实质就是过滤器实现,按例子中再web.xml添加struts2的过滤器

2.2 struts.xml文件

在struts2框架中使用包来管理Action,包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action.在实际应用中,我们应该把一组业务功能相关的Action放在同一个包下。
配置包时必须指定name属性,该name属性值可以任意取名,但必须唯一,如果其他包要继承该包,必须通过该属性进行引用。包的namespace属性用于定义该包的命名空间,命名空间作为访问该包下Action路径的一部分。Namespace属性可以不配置,如果不指定该属性,默认的命名空间为“”
通常每个包都应该继承struts-default包,因为struts2很多核心的功能都是拦截器来实现。当包继承了struts-default才能使用struts2提供的核心功能。Struts-default包是在struts2-core-2.x.x.jar文件中的struts-default.xml中定义。

一个package中可以有多个action

3 Action

3.1 基本概念

Action有一下特点:Struts2框架中Action是一个POJO,没有被代码污染。

POJO(Plain Old Java Objects)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。是它通指没有使用Entity Beans的普通java对象,可以把POJO作为支持业务逻辑的协助类。

Struts2中actions的唯一要求是必须有一个无参数方法返回String或Result对象,并且必须是POJO。如果没有指定no-argument方法,则默认是使用execute()方法

3.2 基类ActionSupport

框架还提供了一个Action组件的基类ActionSupport,它在实现了Action接口的同时实现了execute()方法。

3.3 让Action处理多个请求——通配符

【src/struts.xml】:_* 代表方法名,action 添加 {1} 表示第一个 * 的内容

<struts>
<package name="mylogin" extends="struts-default"> 
    <action name="loginUser_*" class="my.example.UserAction" method="{1} ">
    <result name="success">/success.jsp</result>
    <result name="error">/error.jsp</result>
    <result name="add">/{1}.jsp</result><!-- 跳转add.jsp -->
    <result name="delete">/{1}.jsp</result><!-- 跳转delete.jsp -->
</action>
</package>
</struts>

【src/my.example/User.java】:继承ActionSupport并增加方法,execute()返回值为常量SUCCESSERROR

package my.example;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport{ 

    private User user;//复杂类型

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String execute() throws Exception { 
    // 只有用户名为root,密码为root方可成功登陆 
        if (user.getUsername().equals("root") && user.getPassword().equals("root")) { 
            return SUCCESS; }
        else { 
            return ERROR; 
        } 
    } 

    public String add() {
        return "add";    
    }
    public String delete() {
        return "delete";    
    }
}

【WebContent/login.jsp】:form中的action加_*,*是方法名

<%@ taglib prefix="s" uri="/struts-tags" %> 
<!-- s:stuts标签 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="loginUser"> <!-- 执行action中的默认方法execute() -->
    <s:textfield name="user.username" label="用户名"></s:textfield> 
    <s:password name="user.password" label="密码"></s:password> 
    <s:submit value="确定"/><s:reset value="重置"/> 
</s:form> 
<s:form action="loginUser_add"> <!-- 执行action中的add() -->
    <s:submit value="add"/>
</s:form> 
<s:form action="loginUser_delete"> <!-- 执行action中的delete() -->
    <s:submit value="delete"/>
</s:form> 
</body>
</html>

增加【WebContent/add.jsp】和【WebContent/delete.jsp】,其他页面不变。

【运行结果:】注意网址


【src/struts.xml】还能精简:减少代码冗余。

<struts>
<package name="mylogin" extends="struts-default"> 
    <action name="loginUser_*" class="my.example.UserAction" method="{1} ">
    <result name="success">/success.jsp</result>
    <result name="error">/error.jsp</result>

    <!-- 返回值是add就跳转add,jsp返回值为delete就跳delete.jsp -->   
    <result name="{1}">{1}.jsp</result>

</action>
</package>
</struts>

4 校验机制

4.1 手动校验

【src/struts.xml】:校验不成功返回字符串input

</package>
<package name="mylogin" extends="struts-default"> 
    <action name="loginUser_*" class="my.example.UserAction" method="execute ">
    <result name="success">success.jsp</result>
    <result name="error">error.jsp</result>
    <result name="input">login.jsp</result><!-- 校验不成功时跳转 -->
</action>
</package>

【src/my.example/UserAction.java】:validate()校验方法

package my.example;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport{ 
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }
    //重写父类ActionSupport的校验的方法validate()
    @Override
    public void validate() {
        if(username.equals("admin")) {
            //提示信息username is invalid出现在username字段附近
            this.addFieldError("username", "username is invalid");
        }
        if(password.equals("111")) {
            this.addFieldError("password", "username is invalid");
        }
        if(username.equals("root")&&password.equals("root")) {
            //多个字符串时候,不能指定错误信息提示在哪个字段的附近
            //而是直接出现在<s:actionerror/>处
            this.addActionError("information is invalid");
        }
    }
}

【WebContent/login.jsp】:

<body>
<s:form action="loginUser"> <!-- 执行action中的默认方法execute() -->
    <s:textfield name="username" label="用户名"></s:textfield> 
    <s:password name="password" label="密码"></s:password> 
    <s:submit value="确定"/><s:reset value="重置"/> 
</s:form> 
<s:actionerror/><!-- this.addActionError()报错信息位置 -->
</body>

【结果】:错误提示出现在字段的附件提示错误信息

账号admin密码111:

账号root密码root:

4.2 自动校验

4.2.1 基本数据类型时

【src/my.example/UserAction-validation.xml】:UserAction-validation.xml和UserAction.java放在同一个包下

<?xml version="1.0" encoding="UTF-8"?>
<!--  -->
<!DOCTYPE validators PUBLIC 
 "-//Apache Struts//XWork Validator 1.0.2//EN" 
 "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>

<validator type="requiredstring">
<param name="fieldName">username</param>
<message>用户名不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">password</param>
<message>密码不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">repassword</param>
<message>再次输入密码不可为空</message>
</validator>

<validator type="required">
<param name="fieldName">height</param>
<message>身高不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">email</param>
<message>邮箱不可为空</message>
</validator>

<validator type="required">
<param name="fieldName">birthday</param>
<message>生日不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">blogurl</param>
<message>博客不可为空</message>
</validator>

<validator type="regex">
<param name="fieldName">username</param>
<param name="expression"><![CDATA[(\w{4,20})]]></param>
<message>用户名长度必须在4到20之间且必须是数字和字母</message>
</validator>


<validator type="stringlength">
<param name="fieldName">password</param>
<param name="minLength">6</param>
<message>密码不得小于${minLength}位</message>
</validator>

<validator type="url">
<param name="fieldName">blogurl</param>
<message>博客地址不正确</message>
</validator>

<validator type="email">
<param name="fieldName">email</param>
<message>邮箱地址不正确</message>
</validator>

<validator type="double">
<param name="fieldName">height</param>
<param name="minInclusive">0.7</param>
<param name="maxInclusive">2.5</param>
<message>身高必须在${minInclusive}和${maxInclusive}之间</message>
</validator>

<validator type="date">
<param name="fieldName">birthday</param>
<param name="min">1900-01-01</param>
<param name="max">2010-01-01</param>
<message>出生日期必须在${min}和${max}之间</message>
</validator>

<validator type="fieldexpression">
<param name="fieldName">password</param>
<param name="fieldName">repassword</param>
<param name="expression"><![CDATA[(password==repassword)]]></param>
<message>两次输入的密码必须一致</message>
</validator>

<validator type="fieldexpression">
<param name="fieldName">username</param>
<param name="expression"><![CDATA[(username!='admin')]]></param>
<message>用户名不允许设为admin</message>
</validator>

</validators>

【WebContent/login.jsp】:

<body>
     <s:fielderror cssStyle="color:red;"/><!-- 校检信息提示处 -->

       <s:form action="loginUser" method="POST" theme="simple">
       <table border="1" cellpadding="0" cellspacing="0">
       <tr>
           <td>用户名</td>
           <td>
             <s:textfield name="username"/>
           </td>
       </tr>
       <tr>
           <td>密  码</td>
           <td>
             <s:password name="password"/>
           </td>
       </tr>
       <tr>
           <td>再次输入密码</td>
           <td>
             <s:password name="repassword"/>
           </td>
       </tr>
       <tr>
           <td>出生日期</td>
           <td>
             <s:textfield name="birthday"/>
           </td>
       </tr>
       <tr>
           <td>身高(米)</td>
           <td>
             <s:textfield name="height"/>
           </td>
       </tr>
       <tr>
           <td>电子邮箱</td>
           <td>
             <s:textfield name="email"/>
           </td>
       </tr>
       <tr>
           <td>博客</td>
           <td>
             <s:textfield name="blogurl"/>
           </td>
       </tr>
       <tr>
           <td>&nbsp;</td>
           <td>
             <s:submit value="注册"/>
           </td>
       </tr>
       </table>
    </s:form>
</body>

【src/my.example/UserAction.java】:

package my.example;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport{ 
    private String username;
    private String password;
    private String repassword;
    private double height;
    private Date birthday;
    private String email;
    private String blogurl;

    public Date getBirthday() {

        return birthday;

    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRepassword() {
        return repassword;
    }
    public void setRepassword(String repassword) {
        this.repassword = repassword;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getBlogurl() {
        return blogurl;
    }
    public void setBlogurl(String blogurl) {
        this.blogurl = blogurl;
    }
    public String execute(){
        System.out.println(birthday);
        return SUCCESS;
    }
}

【src/struts.xml】:校验不成功返回字符串input

</package>
<package name="mylogin" extends="struts-default"> 
    <action name="loginUser_*" class="my.example.UserAction" method="execute ">
    <result name="success">success.jsp</result>
    <result name="error">error.jsp</result>
    <result name="input">login.jsp</result><!-- 校验不成功时跳转 -->
</action>
</package>

【结果:】校验器默认的执行顺序是按照在配置文件中由上到下的顺序执行的。框架默认非字段校验器的执行顺序是优于字段校验器的。非字段校验器的执行与字段校验器的执行是分离的,非字段校验器的短路只会影响到与此字段相关的非字段校验器。

4.2.2 复杂数据类型

【src/my.example/User.java】:新建User.java类,把基本数据剪切过来封装。

package my.example;

import java.util.Date;

public class User {
    private String username;
    private String password;
    private String repassword;
    private double height;
    private Date birthday;
    private String email;
    private String blogurl;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRepassword() {
        return repassword;
    }
    public void setRepassword(String repassword) {
        this.repassword = repassword;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getBlogurl() {
        return blogurl;
    }
    public void setBlogurl(String blogurl) {
        this.blogurl = blogurl;
    }
}

【src/my.example/UserAction.java】:添加User复杂数据类型

package my.example;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport{ 
    private User user;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

    public String execute(){
        return SUCCESS;
    }
}

【src/my.example/UserAction-validation.xml】:UserAction-validation.xml和UserAction.java放在同一个包下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC 
 "-//Apache Struts//XWork Validator 1.0.2//EN" 
 "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>
<field name="user">
<field-validator type="visitor">
<param name="context">Reg</param><!-- 名字:要和文件名中间相同 -->
<param name="appendPrefix">true</param><!-- 是否加前缀 -->
<message>用户注册:</message><!-- 前缀描述 -->
</field-validator>
</field>
</validators>

【src/my.example/User-Reg-validation.xml】:User-Reg-validation.xml和User.java放在同一个包下,并且文件名-两横杠中字符串与“context”的值对应-,对基本数据的校检放进新validation

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC 
 "-//Apache Struts//XWork Validator 1.0.2//EN" 
 "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">

<validators>

<validator type="requiredstring">
<param name="fieldName">username</param>
<message>用户名不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">password</param>
<message>密码不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">repassword</param>
<message>再次输入密码不可为空</message>
</validator>

<validator type="required">
<param name="fieldName">height</param>
<message>身高不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">email</param>
<message>邮箱不可为空</message>
</validator>

<validator type="required">
<param name="fieldName">birthday</param>
<message>生日不可为空</message>
</validator>

<validator type="requiredstring">
<param name="fieldName">blogurl</param>
<message>博客不可为空</message>
</validator>

<validator type="regex">
<param name="fieldName">username</param>
<param name="expression"><![CDATA[(\w{4,20})]]></param>
<message>用户名长度必须在4到20之间且必须是数字和字母</message>
</validator>


<validator type="stringlength">
<param name="fieldName">password</param>
<param name="minLength">6</param>
<message>密码不得小于${minLength}位</message>
</validator>

<validator type="url">
<param name="fieldName">blogurl</param>
<message>博客地址不正确</message>
</validator>

<validator type="email">
<param name="fieldName">email</param>
<message>邮箱地址不正确</message>
</validator>

<validator type="double">
<param name="fieldName">height</param>
<param name="minInclusive">0.7</param>
<param name="maxInclusive">2.5</param>
<message>身高必须在${minInclusive}和${maxInclusive}之间</message>
</validator>

<validator type="date">
<param name="fieldName">birthday</param>
<param name="min">1900-01-01</param>
<param name="max">2010-01-01</param>
<message>出生日期必须在${min}和${max}之间</message>
</validator>

<validator type="fieldexpression">
<param name="fieldName">password</param>
<param name="fieldName">repassword</param>
<param name="expression"><![CDATA[(password==repassword)]]></param>
<message>两次输入的密码必须一致</message>
</validator>

<validator type="fieldexpression">
<param name="fieldName">username</param>
<param name="expression"><![CDATA[(username!='admin')]]></param>
<message>用户名不允许设为admin</message>
</validator>

</validators>

【WebContent/login.jsp】:name中参数加上对象user.

<body>
     <s:fielderror cssStyle="color:red;"/><!-- 校检信息提示处 -->

       <s:form action="loginUser" method="POST" theme="simple">
       <table border="1" cellpadding="0" cellspacing="0">
       <tr>
           <td>用户名</td>
           <td>
             <s:textfield name="user.username"/>
           </td>
       </tr>
       <tr>
           <td>密  码</td>
           <td>
             <s:password name="user.password"/>
           </td>
       </tr>
       <tr>
           <td>再次输入密码</td>
           <td>
             <s:password name="user.repassword"/>
           </td>
       </tr>
       <tr>
           <td>出生日期</td>
           <td>
             <s:textfield name="user.birthday"/>
           </td>
       </tr>
       <tr>
           <td>身高(米)</td>
           <td>
             <s:textfield name="user.height"/>
           </td>
       </tr>
       <tr>
           <td>电子邮箱</td>
           <td>
             <s:textfield name="user.email"/>
           </td>
       </tr>
       <tr>
           <td>博客</td>
           <td>
             <s:textfield name="user.blogurl"/>
           </td>
       </tr>
       <tr>
           <td>&nbsp;</td>
           <td>
             <s:submit value="注册"/>
           </td>
       </tr>
       </table>
    </s:form>
</body>

【结果】:当不同的Action调用同一个封装类时,设置不同的前缀信息,就能知道是哪个Action校检有问题。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

客官,赏一瓶怡宝吧。

支付宝
微信