Web开发 | Struts2 - 01.MVC和Struts2流程

1.JavaWeb开发回顾和MVC流程总结和MVC框架简介

MVC的处理流程

  1.浏览器向Servlet(Control)发送请求
  2..Control仅仅只是调度器。接收到请求之后,调用Model的方法来处理用户请求
  3.处理结束后,Servlet会将处理结果存进“指定范围”中,转发到指定视图页面(JSP),在视图页面上取出结果数据,并以合适的格式显示出来。

在上面的流程中,有如下操作是每次都要做的,而且是通用的:
  1.通过request.getParameter来得到请求参数(使用Struts2后不用该方法获取)
  2.将请求参数进行类型转换
  3.对请求参数进行输入校验
  4.文件上传
  ……

框架

  当我们做了N个项目时,项目中总有一些代码在多个项目中是重复的,而且具有通用性质。于是就会把项目中通用的、重复性的代码“抽取”出来,做成自己的库,这就是框架。

为什么选择开源框架:
  1.开源框架经过很多的市场检验,稳定性、性能都能得到较好的保障。
  2.开源框架本身出自经验丰富的开发团队,因此质量也有保证。

MVC框架

  Struts2
  Spring MVC
  JSF(Sun推荐的官方MVC规范,有参考实现RI(Reference Implemention))

Web应用下的MVC示意图
Web应用下的MVC示意图


2.Struts2框架的文件结构及各文件的详细介绍

解压后,得到四个文件夹:
  apps:包含2个web应用war包
    struts2-rest-showcase.war – Struts2关于REST技术的小例子
    struts2-showcase.war – Struts2技术的所有小例子
    …
  docs:API文档,以及相关的Guide。
  lib:Struts2自己的jar包,以及它编译和运行所需要的第三方jar包
  src:Struts2的源代码

Struts2框架的文件结构
Struts2框架的文件结构

*.jar:N个.class文件
*.war:一个Web应用的包(w表示Web)
*.ear:一个企业应用包。包括N个jar包,N个war包(e表示Enterprise)
都是用jar命令压缩的,与zip格式完全兼容。


3.Eclipse的JavaWeb项目中使用Struts2框架

空项目_登录

  在官网(https://struts.apache.org/download.cgi#struts2514.1)下载最新安装包(Struts 2.5.14.1),以核心包struts-2.5.14.1-min-lib.zip为例。

安装Struts2(struts-2.5.14.1-min-lib.zip)

  1、找JAR包。struts-2.5.14.1-min-lib.zip解压出来后lib目录下的所有包。
  2、修改web.xml文件,加载Struts2的核心Filter,让核心Filter过滤所有的用户请求。
  3、Java Resource目录下的src下增加一个Struts2的配置文件struts.xml

Struts2应用的开发步骤

  1、定义能发送请求的页面:页面要么包含表单,要么包含超级链接。个别情况下,用户可以直接以GET方式发送请求,则无需经过这一步。

  2、定义处理用户请求的Action类。Struts2对Action并没有过多的要求,只需要:
    A、实现Action接口或者继承ActionSupport(本身实现了Action接口)
      Action接口中定义了5个字符串常量和一个execute抽象方法(默认)。
    B、为每个请求参数都提供Field,并为之提供相应的setter和getter方法。
    C、该Action类应该有无参数构造器

  3、在struts.xml文件中配置Action。并配置处理结果和物理视图资源之间对应关系。如果使用Convention插件,则该步骤可以省略。
  所有action都需要放在package里配置:

<action…/>元素有如下常用属性:
    - name:指定该action处理哪个请求。
    - class:指定该action对应的处理类。
    - method:指定该action的哪个方法来处理用户请求,默认值为execute。
并为处理返回的字符串,指定相应的物理视图。

  注意:Action中处理用户请求的方法不能有形参声明,返回值是String。

  4、编写视图资源。

用了Struts2之后,底层的运行原理

  1、浏览器发送请求:abc.action。.action后缀可以保留,也可以忽略。
  2、浏览器发送的请求被StrutsPrepareAndExecuteFilter拦截。
    因为我们在web.xml中指定StrutsPrepareAndExecuteFilter来过滤所有的请求。
  3、StrutsPrepareAndExecuteFilter会创建Action实例。
    假如我们请求abc.action,StrutsPrepareAndExecuteFilter会搜索struts.xml文件中name为abc的Action配置,根据class属性“使用反射”来创建Action实例。
  4、调用

Map<StringString>paramMap = request.getParameterMap();//返回所有请求参数
使用循环(String paramName:paramMap.keySet())
{
    //得到请求参数名对应的setter方法
    Action类.getMethod(“set+paramName的首字母大写);
    //得到请求参数对应的值
    String paramValue = paramMap.get(paramName);
    //以Action实例为调用者,调用setter方法,把请求参数值作为参数值传入
    Setter.invoke(actionInst, paramValue);
}

  5、再次“通过反射”来调用method属性所指定的方法。返回一个字符串
  6、根据struts.xml文件中的<result…/>元素的name以及物理视图资源跳转到实际的视图资源。

  POJO(Plain Old Java Object)—— 应该尽量使用POJO编程,尽量避免使用特定框架、特定规范相关的API。

空项目

新建一个动态Web项目
新建一个动态Web项目
新建一个动态Web项目

将struts-2.5.14.1-min-lib.zip解压出来lib下面jar包复制到项目WEB-INF下的lib中
WEB-INF下的lib文件夹
WEB-INF下的lib文件夹

修改WEB-INF下的web.xml文件

  /Struts2/WebContent/WEB-INF/web.xml
程序代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    id="WebApp_ID" version="3.0">
    <filter>
        <filter-name>Struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <!-- 让Struts2的核心Filter拦截所有的用户请求 -->
    <filter-mapping>
        <filter-name>Struts2</filter-name>
        <url-pattern>/*</url-pattern>
     </filter-mapping>
</web-app>

StrutsPrepareAndExecuteFilter快速取包名.类名(Java完整使用类方法)
快速取包名.类名
快速取包名.类名
快速取包名.类名

在src目录下的下新建一个配置文件struts.xml,并进行配置

  /Struts2/src/struts.xml
程序代码如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>
    <!-- 所有的配置都要放在package元素中,而且包必须继承struts-default -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- 1.它是一个通用Action,此处的*表明它可以处理任意的请求 -->
        <!-- 2.亦可以设为Action*,此处的Action为第一个参数,*号为第二个参数 -->
        <action name="*">
            <!-- 1.此处{1}代表*号所匹配的字符串 -->
            <!-- 2.此处若为{1}.{2}.jsp,1代表第一个参数,2代表*号所匹配的字符串 -->
            <result>/WEB-INF/content/{1}.jsp</result>
        </action>
    </package>

</struts>
<!-- END SNIPPET: xworkSample -->

xml智能提示

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>

xml智能提示
xml智能提示

此时即可初步运行项目(基本配置成功)
运行项目
运行项目
运行项目
运行项目

项目运行正确


登录

在WEB-INF下建立文件夹content,放入新建的视图页面
WEB-INF/content/LoginForm.jsp

  /Struts2/WebContent/WEB-INF/content/LoginForm.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>登录</title>
</head>
<body>
<h1>用户登录</h1>
<form action="loginPro" method="post">
用户名:<input type="text" name="user.name" /></br>
密码:<input type="text" name="user.pass" /></br>
<input type="submit" value="登录" /></br>
</form>
</body>
</html>

定义处理用户请求的Action类

定义Action类
定义Action类
定义Action类

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import com.opensymphony.xwork2.Action;

public class LoginProAction implements Action {

        @Override
        public String execute() throws Exception {
            //TODO Auto-generated method stub
            return null;
        }
}
package Struts2.action;

import com.opensymphony.xwork2.Action;

public class LoginProAction implements Action {

        // 可以通过该user来访问请求参数
        private User user;

        //用户请求
        @Override
        public String execute() throws Exception {
            //TODO Auto-generated method stub
            return null;
        }
}

添加setter和getter方法

添加setter和getter方法

添加setter和getter方法

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import com.opensymphony.xwork2.Action;

public class LoginProAction implements Action {

        // 定义一个User类,封装一个user属性
        private User user;

        public User getUser() {
            return user;
        }

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

        //用户请求
        @Override
        public String execute() throws Exception {
            //TODO Auto-generated method stub
            return null;
        }
}

创建User类(规范包的写法)
创建User类
包的命名
注意包的选择
导包

添加setter和getter方法

  /Struts2/src/Struts2/action/domain/User.java
程序代码如下:

package Struts2.action.domain;

import java.util.Date;

public class User {

    private Integer id;
    private String name;
    private String pass;
    private double weight;
    private Date birth;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPass() {
        return pass;
    }
    public void setPass(String pass) {
        this.pass = pass;
    }
    public double getWeight() {
        return weight;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
}

name和pass相同时即为同一个对象,需要使用equals方法来判断。
故重写hashCode及equals。
重写hashCode及equals1
这里写图片描述

  /Struts2/src/Struts2/action/domain/User.java
程序代码如下:

package Struts2.action.domain;

import java.util.Date;

public class User {

    ...

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((pass == null) ? 0 : pass.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (pass == null) {
            if (other.pass != null)
                return false;
        } else if (!pass.equals(other.pass))
            return false;
        return true;
    }
}

获取页面请求参数
视图中已经绑定user,可以通过LoginFrom.java中的user来访问请求参数

  /Struts2/WebContent/WEB-INF/content/LoginForm.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>登录</title>
</head>
<body>
<h1>用户登录</h1>
<form action="loginPro" method="post">
用户名:<input type="text" name="user.name" /></br>
密码:<input type="text" name="user.pass" /></br>
<input type="submit" value="登录" /></br>
</form>
</body>
</html>

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import com.opensymphony.xwork2.Action;

import Struts2.action.domain.User;

public class LoginProAction implements Action {

        // 定义一个User类,封装一个user属性
        // 可以通过该user来访问请求参数
        private User user;

        public User getUser() {
            return user;
        }

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

        //用户请求
        @Override
        public String execute() throws Exception {
            //TODO Auto-generated method stub
            return null;
        }
}

重写LoginFrom.java中的execute方法

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import com.opensymphony.xwork2.Action;

import Struts2.action.domain.User;

public class LoginProAction implements Action {

        ...

        //用户请求
        @Override
        public String execute() throws Exception {
            UserService us = new UserService();
            //此时的user已经可以访问请求参数了
            //调用业务逻辑组件来处理用户登录
            Integer id = us.validateLogin(user);
            if(id > 0)
            {   
                return SUCCESS;//SUCCESS是常量名,它的真实值是“success”
            }
            return ERROR;
        }
}

创建UserService类(规范包的写法与选择)
创建UserService类
规范包的写法与选择
导包

  /Struts2/src/Struts2/action/service/UserService.java
程序代码如下:

package Struts2.action.service;

import java.util.ArrayList;
import java.util.List;

import Struts2.action.domain.User;

public class UserService {
    //模拟数据库
    static List<User> userDb;

    static {
        userDb = new ArrayList<>();
        // 相当于user表中有一条记录
        userDb.add(new User());
    }
}

相对应User.java中的User类创建构造器
有/无参数的构造器

  /Struts2/src/Struts2/action/domain/User.java

创建构造器1
创建构造器2

程序代码如下:

package Struts2.action.domain;

import java.util.Date;

public class User {
    ...

    public User() {}

    public User(Integer id, String name, String pass, double weight, Date birth) {
        super();
        this.id = id;
        this.name = name;
        this.pass = pass;
        this.weight = weight;
        this.birth = birth;
    }
    ...
}

相对应传入参数

  /Struts2/src/Struts2/action/service/UserService.java
程序代码如下:

package Struts2.action.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import Struts2.action.domain.User;

public class UserService {
    //模拟数据库
    static List<User> userDb;

    static {
        userDb = new ArrayList<>();
        // 相当于user表中有一条记录
        userDb.add(new User(1,"123","456",56.2,new Date()));    
    }
}

  此时LoginProAction.java中的execute方法中缺少UserService类的validateLogin方法
execute方法

  /Struts2/src/Struts2/action/service/UserService.java
程序代码如下:

package Struts2.action.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import Struts2.action.domain.User;

public class UserService {
    ...
    public Integer validateLogin(User user) {
        //TODO Auto-generated method stub
        return null;
    }
    ...
}
package Struts2.action.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import Struts2.action.domain.User;

public class UserService {
    ...
    public Integer validateLogin(User user) {
        //遍历数据表中所有User对象
                for(User u : userDb)
                {
                    //如果找到了对应的用户,返回该用户的ID
                    if(u.equals(user))
                    {
                        return u.getId();
                    }
                }
                // 如果循环结束都没有找到,返回-1
                return -1;
    }
    ...
}

  此时已经满足Struts2对Action类的要求,打开struts.xml文件配置Action。
  注意:需要写在标签之前,因为此action具有最高拦截权限。

  /Struts2/src/struts.xml
程序代码如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>
    <!-- 所有的配置都要放在package元素中,而且包必须继承struts-default -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- 该action负责处理loginPro的请求,由Struts2.action.LoginProAction的execute(默认)方法处理 -->
        <action name="loginPro" class="Struts2.action.LoginProAction" >
        </action>

        <!-- 1.它是一个通用Action,此处的*表明它可以处理任意的请求 -->
        <!-- 2.亦可以设为Action*,此处的Action为第一个参数,*号为第二个参数 -->
        <action name="*">
            <!-- 1.此处{1}代表*号所匹配的字符串 -->
            <!-- 2.此处若为{1}.{2}.jsp,1代表第一个参数,2代表*号所匹配的字符串 -->
            <result>/WEB-INF/content/{1}.jsp</result>
        </action>
    </package>

</struts>
<!-- END SNIPPET: xworkSample -->

  此时name的值“loginPro”与视图提交的值(项目中为form表单的action动作)相匹配。
  然后class的值“loginPro”即为请求交由Struts2.包下的LoginProAction类进行处理。
  LoginProAction类的相对应方法(项目中为execute方法)处理完后返回的值需要处理。

  /Struts2/src/struts.xml
程序代码如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">

<!-- START SNIPPET: xworkSample -->
<struts>
    <!-- 所有的配置都要放在package元素中,而且包必须继承struts-default -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- 该action负责处理loginPro的请求,由Struts2.action.LoginProAction的execute(默认)方法处理 -->
        <action name="loginPro" class="Struts2.action.LoginProAction" >
            <result name="success">/WEB-INF/content/welcome.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>

        <!-- 1.它是一个通用Action,此处的*表明它可以处理任意的请求 -->
        <!-- 2.亦可以设为Action*,此处的Action为第一个参数,*号为第二个参数 -->
        <action name="*">
            <!-- 1.此处{1}代表*号所匹配的字符串 -->
            <!-- 2.此处若为{1}.{2}.jsp,1代表第一个参数,2代表*号所匹配的字符串 -->
            <result>/WEB-INF/content/{1}.jsp</result>
        </action>
    </package>

</struts>
<!-- END SNIPPET: xworkSample -->

  运行项目http://localhost:8080/Struts2/LoginForm

运行项目1
运行项目2
运行项目3
运行项目4
项目运行正确


注册_显示用户列表
注册

在WEB-INF下的content文件夹放入新建的视图页面

  /Struts2/WebContent/WEB-INF/content/welcome.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>欢迎</title>
</head>
<body>
登录成功
</body>
</html>

  /Struts2/WebContent/WEB-INF/content/error.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>错误</title>
</head>
<body>
错误页面
</body>
</html>

  /Struts2/WebContent/WEB-INF/content/registForm.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>注册</title>
</head>
<body>
<form action="registPro" method="post">
用户名:<input type="text" name="user.name"/><br>
密码:<input type="text" name="user.pass"/><br>
体重:<input type="text" name="user.weight"/><br>
生日:<input type="text" name="user.birth"/><br>
<input type="submit" value="提交" />
</form>
</body>
</html>

定义处理用户请求的Action类
在原来的LoginProAction新增regist方法

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

        public String regist(){
            UserService us = new UserService();
            us.addUser(user);
            return SUCCESS;
        }

完善addUser方法
addUser

  /Struts2/src/Struts2/action/service/UserService.java
程序代码如下:

    public void addUser(User user) {
        //TODO Auto-generated method stub
    }
    public void addUser(User user) {
        user.setId(new Random().nextInt(99));
        // 相当于把user添加到数据库
        userDb.add(user);
    }

  因为registForm页面注册请求action=”registPro”,则需要在struts.xml页面中进行配置。

action="registPro"

...
<!-- 该action负责处理registPro的请求,由Struts2.action.LoginProAction的"regist"方法处理 -->
        <action name="registPro" class="Struts2.action.LoginProAction" method="regist">
            <result name="success">/WEB-INF/content/welcome.jsp</result>
            <result name="error">/WEB-INF/content/error.jsp</result>
        </action>
...

  运行项目http://localhost:8080/Struts2/registForm

运行项目1
运行项目2
运行项目3
运行项目4
项目运行正确


显示用户列表

在WEB-INF下的content文件夹放入新建的视图页面

  /Struts2/WebContent/WEB-INF/content/listUsers.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>所有用户</title>
</head>
<body>
<table width="600" border="1">
    <tr>
        <th>用户名</th>
        <th>密码</th>
        <th>体重</th>
        <th>生日</th>
    </tr>
    <s:iterator value="users" var="u" >
    <tr>
        <td>${u.name}</td>
        <td>${u.pass}</td>
        <td>${u.weight}</td>
        <td>${u.birth}</td>
    </tr>
    </s:iterator>
</table>
</body>
</html>

  /Struts2/WebContent/WEB-INF/content/welcome.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>欢迎</title>
</head>
<body>
用户:${sessionScope.userId} 登录成功<br>
<a href="${pageContext.request.contextPath}/viewUsers">查看系统中所有用户</a>
</body>
</html>

定义处理用户请求的Action类
定义Action类
定义Action类

  /Struts2/src/Struts2/action/ViewUsersAction.java
程序代码如下:

package Struts2.action;

import com.opensymphony.xwork2.Action;

import Struts2.action.service.UserService;

public class ViewUsersAction implements Action {

    @Override
    public String execute() throws Exception {
        // 控制器永远都要调用service方法
        UserService us = new UserService();
        setUsers(us.getAllUsers());
        return SUCCESS;
    }
}

添加方法

添加方法

  /Struts2/src/Struts2/action/service/UserService.java
程序代码如下:

    ...
    public Object getAllUsers() {
        //TODO Auto-generated method stub
        return null;
    }
    ...
    ...
    public List<User> getAllUsers() {
        // 返回系统中所有的用户实例
        return userDb;
    }
    ...

  /Struts2/src/Struts2/action/ViewUsersAction.java
程序代码如下:

package Struts2.action;

import java.util.List;

import com.opensymphony.xwork2.Action;

import Struts2.action.service.UserService;
import Struts2.action.domain.User;

public class ViewUsersAction implements Action {

    // 为需要传到页面的处理结果也提供Field,并提供setter和getter方法。
        private List<User> users;

        public List<User> getUsers() {
            return users;
        }

        public void setUsers(List<User> users) {
            this.users = users;
        }

    @Override
    public String execute() throws Exception {
        // 控制器永远都要调用service方法
        UserService us = new UserService();
        setUsers(us.getAllUsers());
        return SUCCESS;
    }

}

因为welcome页面请求viewUsers,则需要在struts.xml页面中进行配置

  /Struts2/WebContent/WEB-INF/content/welcome.jsp

welcome页面请求viewUsers
welcome页面请求viewUsers

  /Struts2/src/struts.xml
程序代码如下:

        <!-- 该action负责处理viewUsers的请求,由Struts2.action.ViewUsersAction.java的execute方法处理 -->
        <action name="viewUsers" class="Struts2.action.ViewUsersAction" >
            <result name="success">/WEB-INF/content/listUsers.jsp</result>
        </action>

  运行项目http://localhost:8080/Struts2/registForm

运行项目1
运行项目2
运行项目3


访问Servlet_添加Session、Cookie

如何在action中访问Servlet API
  伪访问:借助于ActionContext。
    ActionContext:
      getSession(模拟访问Http Session);
      getApplication(模拟访问Application)。
  真访问(比如要添加Cookie):借助于ServletActionContext。
    ServletActionContext提供了以下静态方法:
      - static PageContext – getPageContext()
      - static HttpServletRequest – getRequest()
      - static HttpServletResponse – getResponse()
      - static ServletContext – getServletContext()

伪访问

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;

import Struts2.action.domain.User;
import Struts2.action.service.UserService;

public class LoginProAction implements Action {

    ...
        //用户请求
        @Override
        public String execute() throws Exception {
            UserService us = new UserService();
            //此时的user已经可以访问请求参数了
            //调用业务逻辑组件来处理用户登录
            Integer id = us.validateLogin(user);
            if(id > 0)
            {           
                ActionContext actCtx = ActionContext.getContext();
                //使用了一个Map来模拟HTTP Seesion
                Map<String, Object> sess = actCtx.getSession();
                //下面代码,表面上只是向Map存入key-value对,但由于该Map模拟HTTP Seesion
                //因此下面存入的key-value对,实际会存入HTTP Seesion
                sess.put("userId", id);
                return SUCCESS;//SUCCESS是常量名,它的真实值是“success”
            }
            return ERROR;
        }   
    ...
}

  /Struts2/WebContent/WEB-INF/content/welcome.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>欢迎</title>
</head>
<body>
用户:${sessionScope.userId} 登录成功<br>
<a href="${pageContext.request.contextPath}/viewUsers">查看系统中所有用户</a>
</body>
</html>

  运行项目http://localhost:8080/Struts2/LoginForm

运行项目1
运行项目2

真访问

  /Struts2/src/Struts2/action/LoginProAction.java
程序代码如下:

package Struts2.action;

import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;

import Struts2.action.domain.User;
import Struts2.action.service.UserService;

public class LoginProAction implements Action {

    // 定义一个User类,封装一个user属性
    // 可以通过该user来访问请求参数
        private User user;

        public User getUser() {
            return user;
        }

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

        //用户请求
        @Override
        public String execute() throws Exception {
            UserService us = new UserService();
            //此时的user已经可以访问请求参数了
            //调用业务逻辑组件来处理用户登录
            Integer id = us.validateLogin(user);
            if(id > 0)
            {           
                ActionContext actCtx = ActionContext.getContext();
                //使用了一个Map来模拟HTTP Seesion
                Map<String, Object> sess = actCtx.getSession();
                //下面代码,表面上只是向Map存入key-value对,但由于该Map模拟HTTP Seesion
                //因此下面存入的key-value对,实际会存入HTTP Seesion
                sess.put("userId", id);

                //此处如果希望用户登录成功,还要添加Cookie
                //由于添加Cookie必须用HttpServletResponse对象,所以该Action必须与Servlet耦合
                HttpServletResponse response = ServletActionContext.getResponse();
                Cookie cookie = new Cookie("userName" , user.getName());
                cookie.setMaxAge(300000);
                //添加Cookie
                response.addCookie(cookie);

                return SUCCESS;//SUCCESS是常量名,它的真实值是“success”
            }
            return ERROR;
        }

        public String regist(){
            UserService us = new UserService();
            us.addUser(user);
            return SUCCESS;
        }

}

新增视图accessCookies.jps

  /Struts2/WebContent/WEB-INF/content/accessCookie.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>访问Cookie的值</title>
</head>
<body>
访问Cookie的值:${cookie.userName.value}
</body>
</html>

  运行项目
    http://localhost:8080/Struts2/LoginForm
运行项目1
    http://localhost:8080/Struts2/accessCookie
运行项目2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值