一、基础实验——Action的自定义方法

(一)实验目的

1、掌握Struts2 的Action 类中自定义方法的使用;
2、掌握Struts2 中Action 类的不同调用方式和相应的配置方法;
3、掌握Action 的实例化情况,理解Action 与Servlet 在实例化上的区别;
4、理解JSP 文件中获取Action 属性的过程;
5、了解Struts2 支持的Action 处理结束后的结果类型。

(二)基本知识和原理

1、Action 类中的默认方法名是execute()方法,可以被自动调用;
2、在Action 中也允许定义其它方法名,可以同时定义多个方法,分别处理不同的逻辑;
3、当Action 中使用了自定义方法,则该Action 就需要特定的配置,一般有四种调用方式:
(1)在struts.xml 文件中通过method 属性指定方法名;
(2)使用动态方法调用方式(DMI);
(3)使用提交按钮的method 属性;
(4)使用通配符配置Action;
4、Action 类是多实例的,Action 类的属性是线程安全的;
5、在JSP 页面中,可以通过Struts2 标签调用Action 中对应的getter 方法,从而输出Action 的属性值;
6、当一个Action 处理用户请求结束后,返回一个字符串作为逻辑视图名,再通过struts.xml 文件中的配置将逻辑视图名与物理视图资源关联起来;Struts2默认提供了一系列的结果类型(struts-default.xml 配置文件的result-types 标签里列出了所支持的结果类型),结果类型决定了Action 处理结束后,将调用哪种视图资源来呈现处理结果。

(三)实验内容及步骤

  1. 新建Web 工程struts-prj2,并将Struts2 中的8 个核心包添加到工程中;
  2. 在struts-prj2中新建login.jsp页面,作为用户登录的视图;新建loginFail.jsp页面,作为登录失败的视图;新建loginSucess.jsp视图,作为登录成功的视图;
#login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
    <title>登录</title>
</head>
<body>
<s:form method="post" action="login.action">
    <s:textfield name="loginUser.account" key="login.account.lable"/>
    <s:password name="loginUser.password" key="login.password.lable"/>
    <s:submit name="submit" key="login.submit.button"/>
</s:form>
</body>
</html>
#loginFail.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陆失败</title>
</head>
<body>
登陆失败
</body>
</html>
#loginSuccess.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
登录成功
</body>
</html>
  1. 在struts-prj2中新建register.jsp页面,作为用户注册的视图;新建regFail.jsp页面,作为注册失败的视图;新建regSuccess.jsp页面,作为注册成功的视图;
#register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%>
<html>
<head>
    <s:head theme="xhtml"/>
    <sx:head parseContent="true" extraLocales="UTF-8"/>
</head>
<body>
    <s:form action="register.action" method="post" onsubmit="return check()">
        <s:textfield name="loginUser.account" key="register.account.lable"/>
        <s:password name="loginUser.password" key="register.password.lable"/>
        <s:password name="loginUser.repassword" key="register.repassword.lable"/>
        <s:radio name="loginUser.sex" list="#{1:'男', 0:'女'}" key="register.sex.lable"/>
        <sx:datetimepicker name="loginUser.birthday" displayFormat="yyyy-MM-dd" key="register.birthday.lable"/>
        <s:textfield name="loginUser.address" key="register.address.lable"/>
        <s:textfield name="loginUser.phone" key="register.phone.lable"/>
        <s:textfield name="loginUser.email" key="register.email.lable"/>
        <s:submit name="sign up" key="register.submit.button"/>
        <s:reset name="reset" key="register.reset.button"/>
    </s:form>
</body>
</html>
#regFail.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册失败</title>
</head>
<body>
注册失败
</body>
</html>
#regSuccess.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>注册成功</title>
</head>
<body>
    <s:property value=""/>
    <s:if test="%{loginUser.sex==\"1\"}">
        <s:text name="先生, "/>
    </s:if>
    <s:else>
        <s:text name="女士, "/>
    </s:else>
您注册成功了!
<s:set name="user" value="loginUser" scope="session"/>
</body>
</html>
  1. 在struts-prj2 中新建cn.edu.zjut.bean 包,并在其中创建UserBean.java,用于记录用户信息;
package cn.edu.zjut.bean;

public class UserBean {
    private String account="";
    private String password="";
    private String repassword="";
    private String name="";
    private String sex="";
    private String birthday="";
    private String address="";
    private String phone="";
    private String email="";
    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    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 String getName() {
        return name;
    }

    public void setName(String name) {
         = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  1. 在struts-prj2 中新建cn.edu.zjut.service 包,并在其中创建UserService.java,用于实现登录逻辑和注册逻辑;
package cn.edu.zjut.service;

import cn.edu.zjut.bean.UserBean;

public class UserService {
    public boolean login(UserBean loginUser){
        if(loginUser.getAccount().equals(loginUser.getPassword())){
            return true;
        }
        return false;
    }
    public boolean register(UserBean registerUser){
        if(registerUser.getAccount().equals(registerUser.getPassword()) && registerUser.getPassword().equals(registerUser.getRepassword()) && !registerUser.getAccount().equals("")){
            return true;
        }
        return false;
    }
}
  1. 在struts-prj2 中新建cn.edu.zjut.action 包,并在其中创建UserAction.java,定义login()方法和register()方法,参照“实验二Struts 基础应用”写入代码,分别用于调用登录逻辑和注册逻辑;
package cn.edu.zjut.action;

import cn.edu.zjut.bean.UserBean;
import cn.edu.zjut.service.UserService;

public class UserAction {
    private UserBean loginUser;
    public UserBean getLoginUser(){
        return loginUser;
    }
    public void setLoginUser(UserBean loginUser){
        this.loginUser = loginUser;
    }
    public String login(){
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            return "success";
        }
        return "fail";
    }
    public String register(){
        UserService userService = new UserService();
        if(userService.register(loginUser)){
            return "success";
        }
        return "fail";
    }
}
  1. 在工程struts-prj2的src目录中创建struts.xml文件,配置Action并设置页面导航,通过action标签中method属性指定方法名;
<?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> 元素用于进行包配置,在 Struts2 框架中,包用于组织 Action 和拦截器等信息,每个包都是由零个或多个拦截器以及 Action 所组成的集合。-->
    <!--    name:必填属性,用于指定该包的名称,此名称是该包被其他包引用的Key-->
    <!--    namespace:可选属性,用于定义包的命名空间-->
    <!--    extends:可选属性,用于指定该包继承自其他包,其属性值必须是另一个包的name属性值,但该属性值通常设置为struts-default,这样该包中的Action就具有了Struts框架默认的拦截器等功能-->
    <package name="strutsBean" extends="struts-default">
        <!--        action配置指定了需要初始化哪个action类进行处理-->
        <!--        result则指定了对应字符串的处理结果-->
        <action name="login" class="cn.edu.zjut.action.UserAction" method="login">
            <result name="success">/loginSuccess.jsp</result>
            <result name="fail">/loginFail.jsp</result>
        </action>
        <action name="register" class="cn.edu.zjut.action.UserAction" method="register">
            <result name="success">/regSuccess.jsp</result>
            <result name="fail">/regFail.jsp</result>
        </action>
    </package>
</struts>
  1. 编辑Web的web.xml文件,增加Struts2核心Filter的配置;
  2. 配置struts-prj2部署在Tomcat服务器上,访问login.jsp和register.jsp页面,并记录运行结果;

javaeeSSM实验报告_intellij idea

  1. 动态方法调用方式(DMI)
#struts.xml
<action name="UserAction" class="cn.edu.zjut.action.UserAction">
     <result name="loginsuccess">/loginSuccess.jsp</result>
     <result name="loginfail">/loginFail.jsp</result>
     <result name="registersuccess">/regSuccess.jsp</result>
     <result name="registerfail">/regFail.jsp</result>
</action>
#需写入以下语句不然会出现500错误
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
#login.jsp
<s:form method="post" action="UserAction!login">
    <s:textfield name="loginUser.account" key="login.account.lable"/>
    <s:password name="loginUser.password" key="login.password.lable"/>
    <s:submit name="submit" key="login.submit.button"/>
</s:form>
  1. 提交按钮方式
    struts.xml的配置方法同DMI方式
<s:form method="post" action="UserAction">
    <s:textfield name="loginUser.account" key="login.account.lable"/>
    <s:password name="loginUser.password" key="login.password.lable"/>
    <s:submit name="submit" key="login.submit.button" method="login"/>
</s:form>
  1. 通配符方式
#struts.xml
<action name="*Action" class="cn.edu.zjut.action.UserAction" method="{1}">
     <result name="{1}sucess">/{1}Success.jsp</result>
     <result name="{1}fail">/{1}Fail.jsp</result>
</action>
#login.jsp
<s:form method="post" action="loginAction">
    <s:textfield name="loginUser.account" key="login.account.lable"/>
    <s:password name="loginUser.password" key="login.password.lable"/>
    <s:submit name="submit" key="login.submit.button"/>
</s:form>
  1. 修改UserAction.java,增加UserAction类的构造方法UserAction(),增加count属性,用于测试Action的实例化情况
public class UserAction {
    private UserBean loginUser;
    private Integer count=0;
    public UserAction(){
        System.out.println("创建了一个UserAction类对象。");
    }
	#必须要设置get方法才能被<s:property>标签获取
    public Integer getCount() {
        return count;
    }

    public UserBean getLoginUser(){
        return loginUser;
    }
    public void setLoginUser(UserBean loginUser){
        this.loginUser = loginUser;
    }
    public String login(){
        count++;
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            return "loginsuccess";
        }
        return "loginfail";
    }
    public String register(){
        UserService userService = new UserService();
        if(userService.register(loginUser)){
            return "registersuccess";
        }
        return "registerfail";
    }
}

javaeeSSM实验报告_intellij idea_02

  1. 修改struts.xml文件,将UserAction的页面导航设置为redirect结果类型
<action name="login" class="cn.edu.zjut.action.UserAction" method="login">
      <result name="loginsuccess" type="redirect">/loginSuccess.jsp</result>
      <result name="loginfail">/loginFail.jsp</result>
</action>

javaeeSSM实验报告_java_03

(四)实验总结

  • Action的四种自定义方式,method方式最好理解,通过method属性表示该请求需要由哪个方法处理,DMI方式和按钮方式则通过在请求时使用!跟上方法标识来进行处理,通配符方式则通过空出的*号来代替请求中相应位置的字符,通过{num}来填充其他地方的内容。
  • 通过多次访问结合控制台的信息,我们可以判断每次的请求都重新初始化了一个Action,而Servlet则会在第一次访问时创建,期间多次访问的Servlet为同一个。
  • 将type改为redirect之后,发现count值不见了,默认的方式为dispatcher,重定向的方式返回jsp不带有count的值。

dispatcher主要用于返回JSP,HTML等以页面为基础View视图,这个也是Struts2默认的Result类型。

Freemarker或者Velocity是为模板准备数据;

redirect目标地址将无法通过ValueStack等Struts2的特性来获取源Action中的数据;

chain其实只是在一个action执行完毕之后,forward到另外一个action,所以他们之间是共享HttpServletRequest的;

StreamResult等价于在Servlet中直接输出Stream流

二、提高实验——ActionSupport与输入校验

(一)实验目的

  1. 了解Action 接口的作用,理解ActionSupport 类的作用;
  2. 掌握在Struts2 中使用校验器或手工编码的方式,对请求参数进行数据校验的方法,掌握在JSP 页面中显示错误信息和提示信息的方法;
  3. 掌握在Action 中使用国际化资源文件的方法;
  4. 掌握Struts2 内置类型转换器的作用和使用方法。

(二)基本知识和原理

  1. 为了让用户开发的Action 类更规范,Struts2 提供了一个Action 接口,该接口定义了Struts2 的Action 处理类应该实现的规范;
  2. Struts2 还为Action 接口提供了一个实现类:ActionSupport,该类提供了若干默认方法,包括:默认的处理用户请求的方法(excute()方法)、数据校验的方法、添加校验错误信息的方法、获取国际化信息的方法等,部分重要方法列表如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IoQQSwNh-1634041997841)(https:///2021/10/11/dxioaNFUXDKhfgP.png)]
  3. Struts2 框架提供了校验器和手工编码两种方式对请求参数进行数据校验,当Action 类继承了ActionSupport 类,就可以通过定义名为“--validation.xml”的校验规则文件的方法进行校验器校验,也可以通过重写ActionSupport 类的validate()方法或validateXxx()方法进行手动校验;
  4. 在JSP 页面中使用Struts2 标签生成的表单,能将域级别的错误信息将自动显示到表单元素处;
  5. 在JSP 页面中使用fielderror 标签,可以集中显示所有的域级错误信息;使用actionerror 标签,可以显示所有的Action 级别错误信息;使用actionmessage标签,可以显示Action 消息;
  6. Struts2 框架中提供了部分内置的类型转换器,可以将请求参数的String 类型转换成基本数据类型及对应的包装器类型、日期类型、数组类型、集合类型等,当Action 类继承了ActionSupport 类,则内置的类型转换器将默认生效,可以直接使用;
  7. 如需修改默认的类型转换校验信息,则要在Action 类的包中声明名为“Action类名.properties”的局部属性文件;
  8. Struts2 框架同时支持自定义类型转换器,将请求参数转换成任意一种类型。

(三)实验内容及步骤

  1. 修改UserAction类,使其继承ActionSupport类,并在UserAction类中覆盖ActionSupport类的validate()方法,用于对用户登录的请求参数account和password进行校验:若用户名或密码为空,则使用addFieldError(域级)添加错误信息;
public void validate(){
        String account = loginUser.getAccount();
        String pwd = loginUser.getPassword();
        if(account == null || account.equals("")){
            this.addFieldError("loginUser.account", "请输入您的用户名!");
        }
        if(pwd == null || account.equals("")){
            this.addFieldError("loginUser.password", "请输入您的密码! ");
        }
    }
  1. 修改struts.xml文件,在Action的配置中增加validate()方法校验出错时的页面导航()
<action name="login" class="cn.edu.zjut.action.UserAction" method="login">
    <result name="loginsuccess">/loginSuccess.jsp</result>
    <result name="loginfail">/loginFail.jsp</result>
    <result name="input">/login.jsp</result>
</action>

javaeeSSM实验报告_javaeeSSM实验报告_04

  1. 修改login.jsp页面,在表单钱增加fielderror标签,再通过浏览器访问
  2. 修改UserAction.java,再带哦有登录逻辑的login()方法中,对登录情况进行校验:若登录成功,使用addActionMessage()方法添加“登录成功!”的Action提示消息,若登录失败,使用addActionError()方法添加Action级别的错误信息
public String login(){
        count++;
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            this.addActionMessage("登录成功!");
            return "loginsuccess";
        }
        else {
            this.addActionError("用户名或密码错误,请重新输入!");
            return "loginfail";
        }
    }
  1. 修改login.jsp页面增加actionerror标签;修改loginSuccess.jsp,使用actionmessage标签显示Action提示消息
  2. 修改sruts.xml文件中用户登录页面导航设置,将登录失败时转向的页面从loginFail.jsp转为login.jsp

javaeeSSM实验报告_struts_05

  1. 创建"UserAction-login-validation.xml"校验规则文件,使其与UserAction类位于同一目录下,配置校验信息,使用校验器对请求参数进行校验。
<?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="loginUser.account">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>用户名不能为空!!!</message>
        </field-validator>
    </field>
    <field name="loginUser.password">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>密码不能为空!!!</message>
        </field-validator>
    </field>
</validators>

javaeeSSM实验报告_intellij idea_06

  1. 将login.jsp、loginSuccess.jsp、loginFail.jsp三个页面进行国际化处理,把需要进行国际化的内容以键值对形式写入资源文件message_zh_CN.properties和message_en_US.properties中
#message_en_US.properties
#field error message
login.account.null=Please input your account!
login.password.null=Please input your password!
#action error message
login.error= Account or password error, please input again!
#action message
login.success=Login successfully!

#message_zh_CN.properties
#field error message
login.account.null=请输入你的用户名
login.password.null=请输入你的密码!
#action error message
login.error=用户名或密码错误,请再次输入!
#action message
login.success=登录成功
  1. 创建struts.properties文件,加载资源文件
struts.custom.i18n.resources=cn.edu.zjut.local.message
struts.i18n.encoding=GBK
  1. 修改UserAction.java,使用ActionSupport()类的getText()方法,获取国际化资源文件信息
public String login(){
        count++;
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            this.addActionMessage(this.getText("login,success"));
            return "loginsuccess";
        }
        else {
            this.addActionError(this.getText("login.error"));
            return "loginfail";
        }
    }

    public void validate(){
        String account = loginUser.getAccount();
        String pwd = loginUser.getPassword();
        if(account == null || account.equals("")){
            this.addFieldError("loginUser.account", this.getText("login.account.null"));
        }
        if(pwd == null || account.equals("")){
            this.addFieldError("loginUser.password", this.getText("login.password.null"));
        }
    }
  1. 修改UserAction-login-validation.xml,获取国际化资源文件中信息
<validators>
    <field name="loginUser.account">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="login.account.null"></message>
        </field-validator>
    </field>
    <field name="loginUser.password">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="login.password.null"></message>
        </field-validator>
    </field>
</validators>
  1. 运行结果
  2. 修改UserBean.java,将用于保存注册用户生日的变量类型该类Date类型,使用Struts2内置的类型转换器对请求参数进行校验

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ULsVxrTL-1634041997851)(https:///2021/10/12/VcwTdlPWEpg4sIB.png)]

  1. 创建局部属性文件“UserAction.properties”,修改类型转换的校验信息,并使用native2ASCII工具将UserAction.properties重新编码
#UserAction.properties
#其中invalid.fieldvalue不能随意修改,
#loginUser.birthday是请求参数域名,应根据实际需要进行修改
invalid.fieldvalue.loginUser.birthday=生日必须是日期,并符合“yyyy-mm-dd”格式
<action name="register" class="cn.edu.zjut.action.UserAction" method="register">
     <result name="registersuccess">/regSuccess.jsp</result>
     <result name="registerfail">/regFail.jsp</result>
     <result name="input">/register.jsp</result>
</action>

javaeeSSM实验报告_java_07

  1. 创建UserAction-register-validation.xml文件,增加校验信息的配置,使用校验器对用户注册的请求参数进行校验,要求注册时两次密码输入相同、email地址格式符合要求等
<?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="loginUser.email">
        <field-validator type="email">
            <param name="trim">true</param>
            <message>你的电子邮件必须时符合规范的</message>
        </field-validator>
    </field>
    <field name="loginUser.password">
        <field-validator type="fieldexpression" short-circuit="true">
            <param name="expression"><![CDATA[(loginUser.password == loginUser.repassword)]]></param>
            <message>两次密码要相同</message>
        </field-validator>
    </field>
</validators>

javaeeSSM实验报告_javaeeSSM实验报告_08

  1. 修改UserAction类,将validate()的方法名改为validateLogin(),并增加validateRegister()方法
public void validateRegister(){
        String email = loginUser.getEmail();
        String pwd = loginUser.getPassword();
        String repwd = loginUser.getRepassword();
        if(!email.contains("@")){
            this.addFieldError("loginUser.email", this.getText("register.email"));
        }
        if(!pwd.equals(repwd)){
            this.addFieldError("loginUser.repassword", this.getText("register.repassword"));
        }
    }

javaeeSSM实验报告_html_09

(四)实验总结

  • validate()是ActionSupport类的默认方法,重写该方法可自定义校验方式,validateXxx()方法则是首字母大写,基于Xxx动态调用来对不同的请求进行数据校验。
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4agpU0Bl-1634041997855)(https:///2021/10/12/z13a9ns6BHyUiw8.png)]
    required:必填校验器
    requiredstring:必填字符串校验器
    int:整数校验器
    double:双精度浮点数校验器
    date:日期校验器
    expression:表达式校验器
    fieldexpression:字段表达式校验器
    email:电子邮件校验器
    url:网址校验器
    stringlength:字符串长度校验器
    regex:正则表达式校验器
  • 国际化资源需要先创建资源键值对,然后struts.properties启动国际化资源,在xml文件和jsp文件中使用key属性使用,java类中使用getText()方法使用
  • 内置类型转换器的使用需要创建ClassName-way-validation.xml的格式在所在Action类同目录下创建,配置validators,在配置field-validator时要选择对应的type类

三、拓展实验——Action类与ServletAPI

(一)实验目的

  1. 掌握在Action 中访问Servlet API 的四种方法,理解四种方法的区别;
  2. 进一步理解Action 与Servlet 的区别;
  3. 进一步熟悉Struts2 标签的使用方法;

(二)基本知识与原理

  1. Struts2 框架中的Action 类没有与任何Servlet API 耦合,因此Action 类可以脱离Servlet 容器环境进行单元测试;
  2. ActionContext 是com.opensymphony.xwork2 包中的一个类,该类表示一个Action 运行时的上下文;
  3. 当Action 类需要通过请求、会话或上下文存取属性时,可以通过ActionContext类完成,也可以通过实现Struts 提供的接口:RequestAware、SessionAware和ApplicationAware 完成,而不必调用Servlet API 中的HttpServletRequest、HttpSession 和ServletContext 对象,从而保持Action 与Servlet API 的解耦;
  4. 在Action 类中直接访问Servlet API,可以通过实现Struts2 提供的接口:ServletContextAware、ServletRequestAware、ServletResponseAware 完成,也可以通过ServletActionContext 工具类实现,但Action 将与Servlet API 直接耦合。

(三)实验内容及步骤

  1. 修改UserAction类,通过ActionContext获取请求、会话和上下文对象相关联的Map对象来实现存取属性的功能
//ActionContext方式获取请求、会话和上下文对象
    private Map request, session, application;
    public String login(){
        //获取ActionContext对象
        ActionContext ctx = ActionContext.getContext();
        //获取请求、会话和上下文相关联的Map对象
        request = (Map)ctx.get("request");
        session = (Map)ctx.getSession();
        application = (Map)ctx.getApplication();
        //访问applicationn范围的属性值
        Integer counter = (Integer) application.get("counter");
        if(counter == null){
            counter = 1;
        }
        else{
            counter += 1;
        }
        application.put("counter", counter);
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            //设置session范围属性
            session.put("user", loginUser.getAccount());
            //设置request范围属性
            request.put("tip", "您已登录成功");
            return "loginsuccess";
        }
        else{
            return "loginfail";
        }
    }
  1. 修改loginSuccess.jsp页面,从请求、会话和上下文对象中获取属性值并显示
本站访问次数为:<s:property value="#application.counter"/>
<s:property value="#session.user"/>
<s:property value="#request.tip"/>

javaeeSSM实验报告_intellij idea_10

  1. 修改UserAction类,通过实现Struts提供的接口:RequestAware、SessionAware和AppliactionAware,获取请求、会话和上下文对象相关联的Map对象来实现存取属性的功能
public class UserAction extends ActionSupport implements RequestAware, SessionAware, ApplicationAware {
    private UserBean loginUser;
    private Integer count=0;
    public UserAction(){
        System.out.println("创建了一个UserAction类对象。");
    }

    public Integer getCount() {
        return count;
    }

    public UserBean getLoginUser(){
        return loginUser;
    }
    public void setLoginUser(UserBean loginUser){
        this.loginUser = loginUser;
    }
    //接口方式实现
    private Map request, session, application;
    public void setRequest(Map<String, Object> request){
        this.request = request;
    }
    public void setSession(Map<String, Object> session){
        this.session = session;
    }
    public void setApplication(Map<String, Object> application){
        this.application = application;
    }
    public String login(){
        Integer counter = (Integer) application.get("counter");
        if(counter == null){
            counter = 1;
        }
        else{
            counter += 1;
        }
        application.put("counter", counter);
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            session.put("user", loginUser.getAccount());
            request.put("tip", "您已登录成功");
            return "loginsuccess";
        }
        else{
            return "loginfail";
        }
    }
}

javaeeSSM实验报告_intellij idea_11

  1. 修改UseAction,通过接口ServletContextAware、ServletRequestAware、ServletResponseAware直接访问ServletAPI,并实现上述功能
public class UserAction extends ActionSupport implements ServletContextAware, ServletRequestAware, ServletResponseAware {
    private UserBean loginUser;
    private Integer count=0;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private ServletContext application;
    public UserAction(){
        System.out.println("创建了一个UserAction类对象。");
    }

    public Integer getCount() {
        return count;
    }

    public UserBean getLoginUser(){
        return loginUser;
    }
    public void setLoginUser(UserBean loginUser){
        this.loginUser = loginUser;
    }
    //ServletContextAware、ServletRequestAware、ServletResponseAware直接访问ServletAPI
    public void setServletRequest(HttpServletRequest request){
        this.request = request;
    }
    public void setServletContext(ServletContext application){
        this.application = application;
    }
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }
    public String login(){
        Integer counter = (Integer) application.getAttribute("counter");
        if(counter == null){
            counter = 1;
        }
        else{
            counter += 1;
        }
        application.setAttribute("counter", counter);
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            HttpSession session = request.getSession();
            session.setAttribute("user", loginUser.getAccount());
            request.setAttribute("tip", "您已登录成功");
            return "loginsuccess";
        }
        else{
            return "loginfail";
        }
    }

javaeeSSM实验报告_struts_12

  1. 修改UserAction类,通过ServletActionContext工具类直接访问Servlet API,实现上述功能
//ServletActionContext工具类直接访问Servlet API
    public String login(){
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        ServletContext application = ServletActionContext.getServletContext();
        HttpSession session = request.getSession();
        Integer counter = (Integer) application.getAttribute("counter");
        if(counter == null){
            counter = 1;
        }
        else{
            counter += 1;
        }
        application.setAttribute("counter", counter);
        UserService userService = new UserService();
        if(userService.login(loginUser)){
            session.setAttribute("user", loginUser.getAccount());
            request.setAttribute("tip", "您已登录成功");
            return "loginsuccess";
        }
        else{
            return "loginfail";
        }
    }

javaeeSSM实验报告_java_13

  1. 利用Servlet API添加购物车功能,在cn.edu.zjut.bean包中创建Item.java用于记录商品信息
package cn.edu.zjut.bean;

public class Item {
    private String itemID;
    private String name;
    private String description;
    private double cost;

    public Item() {
    }

    public Item(String itemID, String name, String description, double cost) {
        this.itemID = itemID;
         = name;
        this.description = description;
        this.cost = cost;
    }

    public String getItemID() {
        return itemID;
    }

    public void setItemID(String itemID) {
        this.itemID = itemID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
         = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getCost() {
        return cost;
    }

    public void setCost(double cost) {
        this.cost = cost;
    }
}
  1. 在cn.edu.zjut.bean中创建ItemOrder.java用于记录购物车中的一条商品信息和购买数量
package cn.edu.zjut.bean;

public class ItemOrder {
    private Item item;
    private int numItems;

    public ItemOrder() {
    }

    public ItemOrder(Item item){
        setItem(item);
        setNumItems(1);
    }
    
    public ItemOrder(Item item, int numItems) {
        this.item = item;
        this.numItems = numItems;
    }

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }

    public int getNumItems() {
        return numItems;
    }

    public void setNumItems(int numItems) {
        this.numItems = numItems;
    }
}
  1. 在cn.edu.zjut.bean中常见ShoppingCart.java用于记录用户的购物车信息,为简化操作,在购物车的构造函数中加入商品信息
package cn.edu.zjut.bean;

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

public class ShoppingCart {
    private List itemsOrdered;
    public ShoppingCart() {
        itemsOrdered = new ArrayList();
        Item item = new Item("book001", "JAVAEE 技术实验指导教程",
                "WEB 程序设计知识回顾、" + "轻量级JAVAEE 应用框架、"
                        + "企业级EJB 组件编程技术、" + "JAVAEE 综合应用开发.", 19.95);
        ItemOrder itemorder = new ItemOrder(item);
        itemorder.setNumItems(2);
        itemsOrdered.add(itemorder);
    }
    public List getItemsOrdered() {
        return (itemsOrdered);
    }
    public synchronized void addItem(String itemID) {}
    public synchronized void setNumOrdered(String itemID, int numOrdered) {}
}
  1. 修改UserAction类的login方法,当登录成功时,创建ShoppingCart对象并存入会话中
if(userService.login(loginUser)){
            session.setAttribute("user", loginUser.getAccount());
            request.setAttribute("tip", "您已登录成功");
            ShoppingCart shoppingCart = new ShoppingCart();
            session.setAttribute("ShoppingCart", shoppingCart);
            return "loginsuccess";
        }
  1. 修改loginSuccess.jsp页面,从会话中获取购物车信息并显示在页面中
<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: yiyi
  Date: 2021/10/11
  Time: 20:05
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
本站访问次数为:<s:property value="#application.counter"/>
<s:property value="#session.user"/>
<s:property value="#request.tip"/>
<br>
<table border="1">
    <s:iterator value="#session.shoppingcart.itemsOrdered">
        <tr>
            <th>编号</th><th>名称</th><th>说明</th><th>单价</th><th>数量</th>
        </tr>
        <tr>
            <td><s:property value="item.itemID"/> </td>
            <td><s:property value="item.name"/> </td>
            <td><s:property value="item.description"/> </td>
            <td><s:property value="item.cost"/> </td>
            <td><s:property value="numItems"/> </td>
        </tr>
    </s:iterator>
</table>
</body>
</html>

javaeeSSM实验报告_html_14

(四)实验总结

  1. ActionContext方式先通过获取的ActionContext对象,再通过get、getSession、getAppliaction方法获取相应的map对象;
  2. RequestAware, SessionAware, ApplicationAware接口方式通过设置setter方法获取request、session和application;
  3. ServletContextAware、ServletRequestAware、ServletResponseAware方法同样需要通过setter方法获取request、session和application;
  4. ServletActionContext工具类方法通过ServletActionContext对象的get方法获取相应对象;
  5. 1和2是Map类型,3和4是HttpServletRequest、HttpServletResponse和ServletContext类型的;
roperty value="#request.tip"/>
 

 <s:iterator value="#session.shoppingcart.itemsOrdered">



</s:iterator>


编号

名称

说明

单价

数量

<s:property value=“item.itemID”/>

<s:property value=“item.name”/>

<s:property value=“item.description”/>

<s:property value=“item.cost”/>

<s:property value=“numItems”/>



(四)实验总结

  1. ActionContext方式先通过获取的ActionContext对象,再通过get、getSession、getAppliaction方法获取相应的map对象;
  2. RequestAware, SessionAware, ApplicationAware接口方式通过设置setter方法获取request、session和application;
  3. ServletContextAware、ServletRequestAware、ServletResponseAware方法同样需要通过setter方法获取request、session和application;
  4. ServletActionContext工具类方法通过ServletActionContext对象的get方法获取相应对象;
  5. 1和2是Map类型,3和4是HttpServletRequest、HttpServletResponse和ServletContext类型的;