SSH笔记-Struts2的ModelDriven和Prepareable使用

1、Struts 2.0 中的 ModelDriven 拦截器负责把 Action 类以外的一个对象压入到值栈栈顶

2、prepare 拦截器负责准备为 getModel() 方法准备 model

3、ModelDriven可以单独使用,但是Prepareable需要配套ModelDriven

4、使用ModelDriven接口之后需要根据指定的实体类写getModel方法,而且要return这个实体类对象

5、如果用了Prepareable接口之后,要写prepare()方法,按照需要可以对原有方法创建prepareXXX函数,这样的话调用方法的时候struts2就会自动去调用对用prepareXXX函数对应的方法了

6、配置struts.xml

<?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>
    <constant name="struts.action.extension" value="action,do,"></constant>
    <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

    <package name="default" namespace="/" extends="struts-default">

        <action name="Test-*" class="com.demo.sshtest.InfoAction" method="{1}">
            <result name="{1}">/Test-{1}.jsp</result>   
            <result name="success" type="redirectAction">Test-show</result> 
        </action>

        <action name="Test-show" class="com.demo.sshtest.InfoAction" method="show">
            <result name="show">/Test-show.jsp</result> 
        </action>

    </package>
</struts>

配置没什么特别的,只是用了通配符,方便添加和删除、修改这三个操作的跳转,当这三个方法操作成功后会返回”success”,这个时候就调用查询操作并跳转回表单显示页面显示结果

7、调用进入显示数据页的index.jsp

<%@ 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>index</title>
</head>
<body>
    <a href="Test-show">进入数据列表/Enter data list view</a>
</body>
</html>

8、显示数据页面 Test-show.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>    

<!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="Test-add.jsp">添加数据/Add data</a>

    <br>
    <hr>
    <br>

    <table cellpadding="10" cellspacing="0" border="1">
        <thead>
            <tr>
                <td>Id</td>
                <td>Name</td>
                <td>Password</td>
                <td>Descrition</td>
                <td>Edit</td>
                <td>Delete</td>
            </tr>
        </thead>

        <tbody>
            <s:iterator value="#request.map">
                <tr>
                    <td>${id }</td>
                    <td>${name }</td>
                    <td>${pswd }</td>
                    <td>${desp }</td>
                    <td><a href="Test-edit?id=${id }">修改/Update</a></td>
                    <td><a href="Test-delete?id=${id }">删除/Delete</a></td>
                </tr>
            </s:iterator>
        </tbody>

    </table>

</body>
</html>

这些会显示数据的页面一定要记得加<%@ taglib prefix="s" uri="/struts-tags" %>

9、添加数据页面 Test-add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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="Test-show">返回/Back</a>
<br>
<s:form action="Test-add">

        <s:textfield name="name" label="NAME"></s:textfield>
        <s:textfield name="pswd" label="PASSWARD"></s:textfield>
        <s:textfield name="desp" label="DESCRITION"></s:textfield>

        <s:submit></s:submit>       
    </s:form>
</body>
</html>

10、修改数据的页面 Test-edit.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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="Test-show">返回/Back</a>
<br>

    <s:debug></s:debug>

    <br>

    <s:form action="Test-update">

        <s:hidden name="id"></s:hidden>
        <s:textfield name="name" label="Name"></s:textfield>
        <s:textfield name="pswd" label="Password"></s:textfield>
        <s:textfield name="desp" label="Descrition"></s:textfield>

        <s:submit></s:submit>       
    </s:form>

</body>
</html>

这里是通过调用Test-edit这个action进来Test-edit.jsp的,然后更新数据是调用Test-update进行更新操作

11、数据属性类 InfoBean.java

package com.demo.sshtest;

public class InfoBean {

    //用于储存属性参数

    private int id = 0;
    private String name = "";
    private String pswd = "";
    private String desp = "";

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPswd() {
        return pswd;
    }
    public void setPswd(String pswd) {
        this.pswd = pswd;
    }
    public String getDesp() {
        return desp;
    }
    public void setDesp(String desp) {
        this.desp = desp;
    }

    public InfoBean(){}

    public InfoBean(String name, String pswd, String desp) {
        super();
        this.name = name;
        this.pswd = pswd;
        this.desp = desp;
        System.out.println("name:"+this.name);
        System.out.println("pswd:"+this.pswd);
        System.out.println("desp:"+this.desp);
    }

    public InfoBean(int id, String name, String pswd, String desp) {
        super();
        this.id = id;
        this.name = name;
        this.pswd = pswd;
        this.desp = desp;
    }

}

要写空构造函数和构造函数,后面需要用来更新给ModelDriven做实体类赋值用

12、对应增删查改的工具类 Dao.java

package com.demo.sshtest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Dao {

    //-----------------------------------------------------------------------------------------//
    //用于储存从数据库获取到得数据
    public static Map<Integer, InfoBean> map = new TreeMap<Integer, InfoBean>();

    //模拟连接数据库后第一次拿到的数据
    //连接数据库之后可以把获取的值在showData()里面给map赋值
    static{
        map.put(1, new InfoBean(1,"NameA","123456","this is NameA"));
        map.put(2, new InfoBean(2,"NameB","123456","this is NameB"));
        map.put(3, new InfoBean(3,"NameC","123456","this is NameC"));
        map.put(4, new InfoBean(4,"NameD","123456","this is NameD"));
    }
    //-----------------------------------------------------------------------------------------//

    //(增)
    public void addData(InfoBean info){
        int newId = 1;
        //map中有数据,添加一条id为当前最大id+1的数据
        if(map.size()!=0){
            newId = Integer.valueOf(getMaxKey(map)) + 1;
        }
        info.setId(newId);
        map.put(info.getId(), info);
    }

    //(删)
    public void deleteData(int id){
        map.remove(id);
    }

    //(查)
    public List<InfoBean> showData(){
        return new ArrayList<>(map.values());
    }

    //(改)
    public void editData(InfoBean info){
        map.put(info.getId(), info);
    }

    //获取指定id的数据
    public InfoBean getSingleData(Integer infoId){
        return map.get(infoId);
    }

    //-----------------------------------------------------------------------------------------//
    //获取map中key的最大值,后面添加数据id为getMaxKey+1
    public static String getMaxKey(Map<Integer, InfoBean> map) {
        if (map == null) return null;
        Set<Integer> set = map.keySet();
        Object[] obj = set.toArray();
        Arrays.sort(obj);
        return String.valueOf(obj[obj.length-1]);
    }
    //-----------------------------------------------------------------------------------------//
}

都写注释了 ,这里看注释就可以

13、action类 InfoAction.java

package com.demo.sshtest;

import java.util.Map;

import org.apache.struts2.interceptor.RequestAware;

import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

public class InfoAction implements RequestAware,ModelDriven<InfoBean>, Preparable {

    // 实例化信息处理的工具类的实体类
    private Dao dao = new Dao();
    // 实例化信息属性类的实体类
    private InfoBean infoBean = new InfoBean();

    // 获得当前请求中包含request对象中全部attributes的一个map对象
    private Map<String, Object> request;

    @Override
    public void setRequest(Map<String, Object> arg0) {
        this.request = arg0;

    }

    // (增)
    public String add() {
        System.out.println("add");
        dao.addData(infoBean);
        return "success";
    }
    public void prepareAdd(){
        infoBean = new InfoBean();
        System.out.println("prepareAdd");
    }

    // (删)
    public String delete() {
        System.out.println("delete");
        dao.deleteData(infoBean.getId());
        return "success";
    }
    public void prepareDelete(){
        System.out.println("prepareDelete");
        //因为prepare是在set方法之前执行,所以这里getId会为空
        //dao.deleteData(infoBean.getId());
    }

    // (查)
    public String show() {
        System.out.println("show");
        //request.put("map", (dao.showData()));
        return "show";
    }
    public void prepareShow(){
        System.out.println("prepareShow");
        request.put("map", (dao.showData()));
    }

    // (改)
    public String update() {
        System.out.println("update");
        dao.editData(infoBean);
        return "success";
    }
    public void prepareUpdate(){
        System.out.println("prepareUpdate");
        infoBean = new InfoBean();
    }

    //跳转到Test-edit页面,获取并且显示对应id的数据
    public String edit(){
        System.out.println("edit");
        //(1)、传入id
        //(2)、根据id获取InfoBean对象
        InfoBean info = dao.getSingleData(infoBean.getId());
        //(3)、封装栈顶对象,不然页面获取的属性值都是null
        infoBean.setName(info.getName());
        infoBean.setPswd(info.getPswd());
        infoBean.setDesp(info.getDesp());
        return "edit";
    }
    public void prepareEdit(){
        System.out.println("prepareEdit");
    }

    //-------------------------------------------------------------------------//
    //Struts 2.0 中的 modelDriven 拦截器负责把 Action 类以外的一个对象压入到值栈栈顶 
    //而 prepare 拦截器负责准备为 getModel() 方法准备 model

    //Prepareable接口的作用有:
    //1、为二次绑定数据
    //2、作为公共的数据准备函数
    //注意事项:
    //1、prepare()方法是在set()、excute()方法之前运行的
    //2、需要跟ModelDriven一起用(但是ModelDriven可以单独用)
    //3、常用于一个对象多属性,但是页面只显示其中一部分属性的时候
    //4、如果一个action里面有多个方法,为了避免冲突,可以多写一个prepareXXX()函数(XXX代表原来需要执行的函数名)
    //5、其实不用根据前台传入值来调用set方法获取值再来做对应操作的方法(如:add()、show()、update()),都可以把部分操作的代码写到prepareXXX()中
    @Override
    public void prepare() throws Exception {
        System.out.println("prepare");
    }

    //这里使用ModelDriven<Object>,是为了代码方便重用
    //1、ModelDriven只有一个方法,就是getModel(),该方法返回的是你的ModelDrivern泛型中设定的实体类
    //2、ModelDriven的作用就是统一设定一个实体类来接收页面传过来的值,不管哪个表单,只要进入实现ModelDriven接口的这个Action类,就会调用设定的实体类接收对应属性的值
    //3、根据第二点可以知道,写了getModel()之后,Action就不用定义参数和不写对应的getset方法了,因为这个时候Action会自动调用设定实体类中的set方法
    @Override
    public InfoBean getModel() {
        System.out.println("-------getModel-------start");
        System.out.println("id:"+infoBean.getId());
        System.out.println("name:"+infoBean.getName());
        System.out.println("pswd:"+infoBean.getPswd());
        System.out.println("desp:"+infoBean.getDesp());
        System.out.println("-------getModel-------end");
        return infoBean;
    }

}

这里也写了注释,看注释就好了,特别注意的是

  1. 调用edit方法的时候要封装栈顶对象
  2. 引用了ModelDriven和Prepareable接口后一定要写getModel()和prepare()方法
  3. prepareXXX()方法可写可不写,里面的内容怎么写,也是随意
  4. 需要调用的方法或属性少的时候,prepareable的效果看不出来,所以按照情况再决定用不用这个接口

14、项目目录
项目目录

15、运行截图
(1)首页
首页
(2)显示数据页
显示数据页面
(3)添加新数据
添加新数据
(4)修改数据
修改数据
数据显示页面中的数据后面有个Edit按钮,点击之后就会跳转到修改数据的页面,这个时候会把对应记录的数据回显到页面上,id用隐藏域,不显示出来

16、demo地址:
https://download.csdn.net/download/qq_22778717/10275941

17、直接按着一步一步写就能成功,不下载demo应该也可以

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值