struts2学习笔记三访问servlet

     2022-02-14     407

关键词:

结果跳转方式

转发

<!--  转发 -->
        <action name="Demo1Action" class="cn.itheima.a_result.Demo1Action" method="execute" >
            <result name="success" type="dispatcher" >/hello.jsp</result>
        </action>

重定向

<!-- 重定向 -->
        <action name="Demo2Action" class="cn.itheima.a_result.Demo2Action" method="execute" >
            <result name="success" type="redirect" >/hello.jsp</result>
        </action>

转发到Action

<!-- 转发到Action -->
        <action name="Demo3Action" class="cn.itheima.a_result.Demo3Action" method="execute" >
             <result name="success" type="chain">
                     <!-- action的名字 -->
                 <param name="actionName">Demo1Action</param>
                     <!-- action所在的命名空间 -->
                 <param name="namespace">/</param>
             </result>
        </action>

重定向到Action

<!-- 重定向到Action -->
        <action name="Demo4Action" class="cn.itheima.a_result.Demo4Action" method="execute" >
            <result  name="success"  type="redirectAction">
                 <!-- action的名字 -->
                 <param name="actionName">Demo1Action</param>
                 <!-- action所在的命名空间 -->
                 <param name="namespace">/</param>
            </result>
        </action>

Struts2访问servlet的API

在Struts2中,Action并没有直接和Servlet API进行耦合,即在Struts2的Action中不能直接访问Servlet API。这是Struts2中Action的重要改良之一,方便Action进行单元测试。

在Struts2中,访问Servlet API有3中方法,具体如下:

通过ActionContext类访问

ActionContext是Action执行的上下文对象,保存了Action执行所需要的所有对象,包括parameters,request,Session,application等。下面列举ActionContext类访问Servlet API的几个常用方法,具体如表所示。

//如何在action中获得原生ServletAPI
public class Demo5Action extends ActionSupport {

    public String execute() throws Exception {
        //request域=> map (struts2并不推荐使用原生request域)
        //不推荐
        Map<String, Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");
        //推荐
        ActionContext.getContext().put("name", "requestTom");
        //session域 => map
        Map<String, Object> sessionScope = ActionContext.getContext().getSession();
        sessionScope.put("name", "sessionTom");
        //application域=>map
        Map<String, Object> applicationScope = ActionContext.getContext().getApplication();
        applicationScope.put("name", "applicationTom");
        
        return SUCCESS;
    }
}

Struts2中,每次提交请求都是不同的线程,每个线程都会绑定一个新的action实例。所以和request的生命周期相同。

通过ServletActionContext访问

 为了直接访问Servlet API,Struts2框架还提供了ServletActionContext类,该类包含了几个常用的静态方法,具体如下:

//如何在action中获得原生ServletAPI
public class Demo6Action extends ActionSupport {
    //并不推荐
    public String execute() throws Exception {
        //原生request
        HttpServletRequest request = ServletActionContext.getRequest();
        //原生session
        HttpSession session = request.getSession();
        //原生response
        HttpServletResponse response = ServletActionContext.getResponse();
        //原生servletContext
        ServletContext servletContext = ServletActionContext.getServletContext();
        return SUCCESS;
    }
}

通过实现接口方式访问

 上面的两种方式都无法直接获得Servlet API实例,为了在Action中直接访问Servlet API,Struts2还提供了一系列接口,具体如下:

//如何在action中获得原生ServletAPI
public class Demo7Action extends ActionSupport implements ServletRequestAware {
    
    
    private HttpServletRequest request;

    public String execute() throws Exception { 
        
        System.out.println("原生request:"+request);
        return SUCCESS;
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }
}

获取参数

以前的Servlet开发中,获取界面传递的参数,然后封装到javabean中,然后将javabean传递到业务层。需要两步操作。在Struts2中,自动将参数进行了封装。Struts2将数据的封装分成两大类,一类被称为是属性驱动,一类被称为是模型驱动。

每次请求到来时,都会创建一个新的Action实例。Action是线程安全的,可以使用成员变量接收参数。

属性驱动可以细分成两种:

  1. 只需要提供属性的set方法即可
  2. 通过表达式方式直接封装到对象中。

属性驱动

提供属性set方法的方式

package cn.itheima.c_param;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

//struts2如何获得参数
//每次请求Action时都会创建新的Action实例对象
public class Demo8Action extends ActionSupport  {
    
    public Demo8Action() {
        super();
        System.out.println("demo8Action被创建了!");
    }


    //准备与参数键名称相同的属性
    private String name;
    //自动类型转换 只能转换8大基本数据类型以及对应包装类
    private Integer age;
    //支持特定类型字符串转换为Date ,例如 yyyy-MM-dd
    private Date   birthday;
    

    public String execute() throws Exception { 
        
        System.out.println("name参数值:"+name+",age参数值:"+age+",生日:"+birthday);
        
        return SUCCESS;
    }


    public String getName() {
        return name;
    }


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


    public Integer getAge() {
        return age;
    }


    public void setAge(Integer age) {
        this.age = age;
    }


    public Date getBirthday() {
        return birthday;
    }


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


    
}
<form action="${pageContext.request.contextPath}/Demo8Action">
        用户名:<input type="text" name="name" /><br>
        年龄:<input type="text" name="age" /><br>
        生日:<input type="text" name="birthday" /><br>
        <input type="submit" value="提交" />
    </form>

以上方式不够优雅,在类中存在大段的set/get方法,不利于代码维护。

把属性和相应的getter/setter方法从action中提取出来,单独作为一个值对象,一般以javaBean来实现,所封装的属性和表单的属性一一对应,JavaBean将称为数据传递的载体。

页面提供表达式方式

package cn.itheima.c_param;

import com.opensymphony.xwork2.ActionSupport;

import cn.itheima.domain.User;

//struts2如何获得参数-方式2
public class Demo9Action extends ActionSupport  {
    //准备user对象
    private User user;

    public String execute() throws Exception { 
        
        System.out.println(user);
        
        return SUCCESS;
    }

    public User getUser() {
        return user;
    }

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

    
}
    <form action="${pageContext.request.contextPath}/Demo9Action">
        用户名:<input type="text" name="user.name" /><br>
        年龄:<input type="text" name="user.age" /><br>
        生日:<input type="text" name="user.birthday" /><br>
        <input type="submit" value="提交" />
    </form>

以上实现方式需要在表单里以user.name的方式,看起来怪怪的。

模型驱动

 通过实现ModelDriven接口来接收请求参数,Action类必须实现ModelDriven接口,并且要重写getModel()方法,这个方法返回的就是Action所使用的数据模型对象。

模型驱动方式通过JavaBean模型进行数据传递。只要是普通的JavaBean,就可以充当模型部分。采用这种方式,JavaBean所封装的属性与表单的属性一一对应,JavaBean将成为数据传递的载体。

大部分我们会优先使用该方式。因为Struts2内部有很多结果围绕模型驱动设计的。但如果页面向多个对象中封装,那么就需要使用属性驱动的方式二了。

//struts2如何获得参数-方式2
public class Demo10Action extends ActionSupport implements ModelDriven<User> {
    //准备user 成员变量
    private User user =new User();

    public String execute() throws Exception { 
        
        System.out.println(user);
        
        return SUCCESS;
    }

    @Override
    public User getModel() {
        return user;
    }
}
    <form action="${pageContext.request.contextPath}/Demo10Action">
        用户名:<input type="text" name="name" /><br>
        年龄:<input type="text" name="age" /><br>
        生日:<input type="text" name="birthday" /><br>
        <input type="submit" value="提交" />
    </form>

集合类型的参数封装

在实际开发中,有些时候我们需要批量插入用户或者批量插入其他的对象,在Action中需要接受到这多个Action中封装的对象,然后传递给业务层。这时候就需要将表单中的数据封装到集合中。

package cn.itheima.c_param;

import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

//struts2 封装集合类型参数
public class Demo11Action extends ActionSupport  {
    //list
    private List<String> list;
    //Map
    private Map<String,String> map;
    
    
    public String execute() throws Exception { 
        
        System.out.println("list:"+list);
        System.out.println("map:"+map);
        
        return SUCCESS;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

}
<form action="${pageContext.request.contextPath}/Demo11Action" method="post" >
        list:<input type="text" name="list" /><br>
        list:<input type="text" name="list[3]" /><br>
        map:<input type="text" name="map['haha']" /><br>
        <input type="submit" value="提交" />
    </form>

 

struts2学习笔记(代码片段)

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2一.Struts2简介Struts2是一个MVC开发模式的框架,用来处理用户请求,代替Servl... 查看详情

servlet学习笔记(代码片段)

Servlet工作原理和生命周期1)当浏览器第一次访问Servlet时,服务器会根据浏览器访问的路径,例如/Demo2,在web.xml文件中找到该Servlet的全路径,进行反射。2)调用init()为Servlet作初始化工作3)调用doXxxxx()为浏览器响应4)如果浏览... 查看详情

struts2学习笔记(代码片段)

Struts2登录2Struts2的常用配置3Struts2对团队开发的支持(多配置文件)3Struts2对ModelDriven模式的支持3Struts2中直接对Action中的对象进行赋值(不new)4Struts2的Action访问Servlet API4Struts2命名空间设置:5Struts2的字符集设置:5Struts2的Action包含多个... 查看详情

struts2从头到脚--学习笔记(自认为比较重要的)

一、Struts2框架介绍Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互Struts2=struts1+webwork核心点:1.拦截器interceptor2.Action3.ognl与valueStack... 查看详情

struts2学习笔记--ognl表达式1

  struts2标签库主要使用的是OGNL语言,类似于El表达式,但是强大得多,它是一种操作对象属性的表达式语言,OGNL有自己的优点:能够访问对象的方法,如list.size();能够访问静态属性和静态方法,只需要在类名前,方法前加上@,如@[email ... 查看详情

学习笔记struts2类型转换

为什么需要类型转换在基于HTTP协议的Web应用中客户端请求的所有内容(表单中提交的内容等)都以文本编码的方式传输到服务器端但服务器端的编程语言(如Java)有着丰富的数据类型如intbooleanDate等等因此当这些参数进入应用程序时... 查看详情

servlet学习笔记_1

一.动态页面和静态页面  动态页面&静态页面:如果浏览器在不同时刻不同条件下访问web服务器的某个页面,浏览器所获得的页面内容会发生变化,那么这种页面称之为动态页面.动态页面和静态页面的区别在于针对页面的访问... 查看详情

servlet学习笔记_2

一.Servlet线程安全问题1.servlet的线程安全问题.servlet引擎采用多线程的模式运行,它为并发的每个访问请求都预备一个线程来相应,但是由于只有一个servlet对象,因此,如果多个线程同时调用servlet的service方法,那么可能会触发线程安全... 查看详情

javaweb学习笔记(持续更新)(代码片段)

javaweb学习笔记一、JavaWeb简介二、认识Servlet1、什么是Servlet?2、请求路径3、tomcat4、Servlet的使用三、Servlet简单应用1、创建Servlet的方式:2、Serlvet的生命周期3、路径与servlet绑定的方式4、servlet种的request和response4、服务器... 查看详情

javaweb学习笔记(持续更新)(代码片段)

javaweb学习笔记一、JavaWeb简介二、认识Servlet1、什么是Servlet?2、请求路径3、tomcat4、Servlet的使用三、Servlet简单应用1、创建Servlet的方式:2、Serlvet的生命周期3、路径与servlet绑定的方式4、servlet种的request和response4、服务器... 查看详情

servlet与缓存-学习笔记(代码片段)

对于浏览器的刷新而言,当浏览器缓存中有资源,也会×××端要资源,只有在回车访问情况下,才找缓存2)可以通过重写getLastModified()方法来阻止每次刷新都访问服务端,以减轻服务端的压力3)如果要实现一种高级功能,即客户端... 查看详情

struts2学习

1.Struts2的Servlet的API的访问  1.1  完全解耦合的方式    ActionContextcontext=ActionContext.getContext();    通过context获取request、response等          *****注意:这种方式只能获得代表request、session、applicati... 查看详情

jsp学习笔记(包括servlet,mysql基本语法,jdbc,struts2简单知识)

用<frameset></frameset>将页面分为几部分。<framesetrows(或cols)="20%,*(或x%),x%....."> (表示将页面分为几部分!rows表示横着分,cols表示竖着fen) <framesrc="*.html"></frame> <frame... 查看详情

jsp学习笔记(包括servlet,mysql基本语法,jdbc,struts2简单知识)

用<frameset></frameset>将页面分为几部分。<framesetrows(或cols)="20%,*(或x%),x%....."> (表示将页面分为几部分!rows表示横着分,cols表示竖着fen) <framesrc="*.html"></frame> <frame... 查看详情

servlet的一些细节--学习笔记(代码片段)

Servlet细节1)浏览器访问的url-pattern只是一个符合格式的任意字符串,以/开头2)一个Servlet的url-pattern可以是1个或多个,有二种形式;a).xxb)/xx/注意:/不能一起直接使用3)/和.do的映射关系,.do最后4)程序员编写的Servlet其实是由tomca... 查看详情

cookies显示用户上次访问的时间学习笔记(代码片段)

Cookie.setMaxAge(72460*60)Cookie.setPath(“/day0X”);Httpwatch观察Cookie.setMaxAge(0)删除同名Cookieimportjava.io.IOException;importjava.util.Date;importjavax.servlet.ServletException;importjavax.servlet.http. 查看详情

struts2系列:与servletapi解耦(servlet相关对象访问)

在程序里面,讲究“高内聚,低耦合”。Struts2采用MVC架构,使用Action来处理http请求并进行响应,而不使用Servlet。但是,我们知道,Servlet的含义就是“服务器端的小应用程序”,它包含了HttpServletRequest、HttpServletResponse、HttpSessio... 查看详情

ssh学习

SSH学习笔记SSH:struts+hibernate+spring第一部分:struts2(没有数据库)struts2简介servlet解耦,实现了MVC的思想;struts2配置文件的标签packagename:唯一标识一个包,不能重名;extends:继承其他包,可以直接使用该包中的资源;abstract:true... 查看详情