快速入门Struts2(上篇)一个案例入门Struts2


1 Struct2 ?

Struct2是一个基于MVC设计模式的Web应用层框架。

Struct2中用action取代了Servlet,action是类,里面对Servlet的一些操作进行了封装,可以大大简化代码的复杂度,已经解决了传统Servlet的一些弊端,需要注意的是,action并不是一个脱离Servlet的东西,其底层依然是Servlet 。

2 一个案例入门Struct2

前记 : Struct2开发包与资源下载 , 本文用struct-2.3.24版本 。

案例目标: 使用Struts2框架完成用户的添加功能,使用普通Servlet完成用户列表功能(下一篇中讲解struts2搭配ognl操作值栈的方法)。

2.1 搭建项目环境

Struts2用到的jar包: 导入struts-2.3.24\apps\struts2-blank.war\WEB-INF\lib下的所有jar包 。

JSTL表达式的jar包(myEclipse不需要) : 自行下载或文尾下载项目中有。

MySQL,创建数据库: create database db_strut ;

DAO采用JPA的开发https://blog.csdn.net/zyqblog/article/details/80725763

User实体类注解配置如下:

/**
 * User实体类
 * @author zhaoyuqiang
 *
 */
@Entity
@Table(name="tb_user")
public class User {
    @Id
    @Column(name="user_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long userId;
    @Column(name="user_name")
    private String userName ;
    @Column(name="user_age")
    private Integer userAge ;
    @Column(name="user_phone")
    private String userPhone ;
    /*
     * 此处省略getter和setter方法
     */
}

2.2 配置核心过滤器(web.xml)

过滤器在服务器启动时创建,创建时执行init()方法,该方法会加载配置文件(包含自己创建的struts.xml,以及web.xml和自带的配置文件等)

web.xml

<!--导入约束,该约束在struct-2.3.24\apps\struts2-blank.war\WEB-INF\web.xml中有-->
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<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>

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter上ctrl+点击,导入struct-2.3.24\src文件夹。

2.3 添加用户.jsp与用户列表.jsp

addUser.jsp

<form action="${pageContext.request.contextPath}/user_addUser.action" method="post">
    用户名:<input type="text" name="userName" /><br>
    年  龄:<input type="text" name="userAge" /><br>
    电  话:<input type="text" name="userPhone" /><br>
    <input type="submit" value="添加"/>
</form>

listAll.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<a href="${pageContext.request.contextPath}/user_findAll">点击这里查看所有用户</a>
<table>
   <tr>
      <td>名字</td>
      <td>年龄</td>
      <td>手机</td>
   </tr>
 <c:forEach items="${listUser}" var="user">
   <tr>
      <td>${user.userName}</td>
      <td>${user.userAge}</td>
      <td>${user.userPhone}</td>
   </tr>
 </c:forEach> 
</table>

2.4 编写action类

action是一个普通类,完全不用继承或实现任何接口用来完成action的编写,但Struts2提供了2种方法来让action的编写变的更加方便,一种是实现一个Action接口,另一种是继承ActionSupport,而第二张是比较常用的,因为ActionSupport类中提供了很多的默认方法,比Action接口更加强大。

package edu.kmust.action;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import edu.kmust.entity.User;
import edu.kmust.service.UserService;
/**
 * User web层
 * @author zhaoyuqiang
 *
 */
public class UserAction extends ActionSupport implements ModelDriven<User>{
    private UserService userService = new UserService() 
    private User user = new User(); //创建实体类对象
    /**
     * 添加用户
     * @return
     */
    public String addUser() {
        /**
         * struts获取表单并封装数据(方法2): 常用
         *     模型驱动封装,要求:
         *         1. 表单输入项name属性值和实体类属性名一致
         *         2. action要实现ModelDriven<实体类名>接口
         *         3. 在action里面手动创建实体类对象
         *         4. 实现该接口的getModel方法,并且返回实体类对象
         *     完成上述3个要求后,struts2会自动把表单数据封装到实体类对象中    
         *        
         */
        /*System.out.println(user.getUserName()+","+user.getUserAge()+","+user.getUserPhone());*/
        userService.addUser(user);          
        return "success_addUser" ;
    }
    /**
     * 查询所有用户
     * @return
     */
    public String findAll() {
        List<User> listUser = userService.findAll();
        /**
         * 利用Servlet的方式操作域对象 :
         *      使用ServletActionContext类
         *      只演示request域,session和ServletContext是类似的。
         */
        HttpServletRequest request = ServletActionContext.getRequest();
        request.setAttribute("listUser", listUser); 

        return  "success_findAll" ;
    }
    /**
     * 跳转到添加页面
     * @return
     */
    public String toaddPage() {
        return "success_toAddPage" ;
    }
    /**
     * 实现ModelDriven接口中的方法
     */
    @Override
    public User getModel() {
        // TODO Auto-generated method stub
        return user;
    }
}

上述action中,查询所有用户功能用到的是Servlet的那一套原始方法(Struts2+OGNL操作值栈的方法下一篇中说明),添加用户方法中,获取表单数据并封装的方法是Struts2框架中的模型驱动封装方法,这是最常用的方法,除此之外还有其他一些方法:

  • Struts框架提供的另一种方法:属性封装
public class UserAction extends ActionSupport {
    //定义实体类变量,并生成setter方法
    private String userName ;
    private int userAge ;
    private String userPhone ;  
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public void setUserAge(int userAge) {
        this.userAge = userAge;
    }
    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }
    /**
     * 添加用户
     * @return
     */
    public String addUser() {    
        /**
         * struts获取表单并封装数据(方法1)
         *    属性封装,要求:
         *      1. 在action成员变量位置定义实体变量,要求该变量与表单输入项的name属性之一样
         *      2. 生成变量的set方法
         *    完成上述两点,则struts2自动把表单数据封装到该实体变量中,缺点是把数据封装到对象中时依然需要最原始的方式
         */
        User user = new User();
        user.setUserName(userName);
        user.setUserAge(userAge);
        user.setUserPhone(userPhone);       System.out.println(user.getUserName()+","+user.getUserAge()+","+user.getUserPhone());           
        return "success_addUser" ;
    }   
}
  • Struts框架提供的还有一种方法:表达式封装
public class UserAction extends ActionSupport {
    //声明实体类,并且生成set和get方法
    private User user ;     
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }   
    /**
     * 添加用户
     * @return
     */
    public String addUser() {
        /**
         * struts获取表单并封装数据(方法3)
         *     表达式封装,(也可以叫做属性封装的另一种方法),要求:
         *       1. action中声明实体类
         *       2. 生成实体类的set和get方法
         *       3. 表单输入项目的name属性值写表达式形式
         *    完成上述3个要求后,struts2会自动把表单数据封装到声明的实体类中
         *       
         */     System.out.println(user.getUserName()+","+user.getUserAge()+","+user.getUserPhone());       
        return "success_addUser" ;
    }
}
<form action="${pageContext.request.contextPath}/user_add.action" method="post">
    用户名:<input type="text" name="user.userName" /><br>
    年  龄:<input type="text" name="user.userAge" /><br>
    电  话:<input type="text" name="user.userPhone" /><br>
    <input type="submit" value="添加"/>
</form>
  • Sevlet提供的两种方法:属性封装
       /**
         * 利用Servlet获取表单数据并封装(方法1) : 
         *      使用ActionContext类获取 
         */
        ActionContext context = ActionContext.getContext();
        Map<String, Object> map = context.getParameters() ;
        //遍历map,查看获取的表单数据        
        Set<String> keys = map.keySet();
        for(String key: keys) {
            Object[] obj = (Object[]) map.get(key);
            System.out.println(Arrays.toString(obj));
        }
        /**
         * 利用Servlet获取表单数据并封装(方法2) :
         *     使用ServletActionContext类获取表单数据 (习惯使用)
         */
        HttpServletRequest request = ServletActionContext.getRequest();
        String userName = request.getParameter("userName");
        int userAge = Integer.valueOf(request.getParameter("userAge"));
        String userPhone = request.getParameter("userPhone") ;
        //封装到实体类对象中
        User user = new User();
        user.setUserName(userName);
        user.setUserAge(userAge);
        user.setUserPhone(userPhone);
        System.out.println(user.getUserName()+","+user.getUserAge()+","+user.getUserPhone());

2.5 配置核心配置文件(struts.xml)

根据分模块开发的思想,我的个人配置文件写在了action包下struts_zhaoyuqiang.xml,核心配置文件struts.xml在src下(名称位置固定)。

struts_zhaoyuqiang.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
      导入约束,在struct-2.3.24\apps\struts2-blank.war\WEB-INF\src\java中struts.xml文件,里面有下面的约束
 -->
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
  <!-- 
       package标签
         name : 类似于区分不同类的包一样,该名字用来区分不同action,没有实际意义
       extends : 固定值,用来说明package里面配置的类具有Action功能
       namespace : 与action标签里面的name值构成访问路径,可以不写
    -->
    <package name="userDemo" extends="struts-default" namespace="/">
       <!-- 
             action标签 
                name : 指定Action处理请求的URL
                  class : 指定Action对应的类
                  method : 指定请求Action时调用的方法,通配符方法,例如user_*_*_*,则{1}、{2}、{3}分别表示从左往右的三个*
             result标签 
                name : 方法返回值
                  type :  dispatcher:跳转到某一个页面
                       redirect : 重定向到某一页面
                       redirectAction : 重定向到某一action,路径写目标action的name属性值    
          -->
         <action name="user_*" class="edu.kmust.action.UserAction" method = "{1}">
            <result name="success_findAll">/jsp/user/listAll.jsp</result>
            <result name="success_toAddPage">/jsp/user/addUser.jsp</result>
            <result name="success_addUser" type="redirectAction">user_findAll</result>
         </action>
         <!-- 上面的通配符表示法是为了简化代码,也可以用下面的普通方法 -->
         <!-- <action name="user_toAddPage" class="edu.kmust.action.UserAction">
            <result name="success_toAddPage">/jsp/user/addUser.jsp</result>
         </action>
         <action name="user_addUser" class="edu.kmust.action.UserAction">
            <result name="success_addUser" type="redirectAction">user_findAll</result>
         </action>
         <action name="user_findAll" class="edu.kmust.action.UserAction">
            <result name="success_findAll">/jsp/user/listAll.jsp</result>
         </action> -->
    </package>
</struts>

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
    导入约束,在struct-2.3.24\apps\struts2-blank.war\WEB-INF\src\java中struts.xml文件,里面有下面的约束
  -->
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!-- 
         constant标签 : 常量的配置
            struts.i18n.encoding :设置编码,用于表单提交数据时的中文乱码处理           
     -->
   <constant name="struts.i18n.encoding" value="UTF-8"></constant>
   <!-- 导入自己配置的文件 -->
     <include file="edu/kmust/action/struts_zhaoyuqiang.xml"></include>
</struts>   

3 执行过程分析

这里写图片描述
上述过程的反射代码,可以写成如下:

Class clazz = Class.forName("action全路径");
Method m = clazz.getMethod("execute"); //得到名称是execute的方法
Object obj = m.invoke(); //方法执行

4 本文代码资源下载

本文完整运行代码下载地址:

! 等本系列写完一起上传 。

猜你喜欢

转载自blog.csdn.net/g425680992/article/details/80778214