ssh备考-05Struts2 Action类下的重要API(原生Servlet的API、跳转配置、框架自身的数据封装、自定义拦截器)
目录
一、Struts框架中如何使用原生Servlet的API
方法一、使用ActionContext类(完全解耦合的方式)(不好用,了解)
demo1.jsp
demo1Action.java ★
struts.xml
suc.jsp
方法二、使用ServletActionContext类(原生Servlet的API的方式)(好用,掌握)★
demo1.jsp里加上
demo2Action.java
小插曲:页面的跳转result的配置总结
1.全局结果页面配置
2.跳转类型设置
dispatcher
redirect
redirectAction
二、struts2专门的数据封装 ★
1.属性驱动方式(封装到Action内定义的属性里)★
demo2.jsp
struts.xml
Regist1Action.java
2.属性驱动方式(封装到action的类成员变量里 前端要写OGNL麻烦 )(了解即可)
demo2.jsp 注意name写法
struts.xml
User.java
Regist2Action.java
3.模型驱动(前端name值不用写OGNL,也可封装到javaBean类对象中)★
前端demo2.jsp 写法没啥特殊之处了
struts.xml
Regist3Action.java
三、拦截器
struts框架环境如何搭建上篇已经介绍 今日资料下载: 直接下载struts2_2.zip 网盘备份下载
一、Struts框架中如何使用原生Servlet的API
案例需求:使用Struts2作为WEB层完成客户的新增功能
提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的页面上。
* 提供JSP注册的页面
<h3>注册页面</h3>
<form action="${ pageContext.request.contextPath }/xxx.action" method="post">
姓名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="注册" />
</form>
方法一、使用ActionContext类(完全解耦合的方式)(不好用,了解)
Struts2框架中提供了一个类,ActionContext类,该类中提供一些方法,通过方法获取Servlet的API
一些常用的方法如下:
static ActionContext getContext() -- 获取ActionContext对象实例(这么获取自己,不需要new)
Map<String,Object> getParameters() -- 获取请求参数,相当于request.getParameterMap();
Map<String,Object> getSession() -- 获取的代表session域的Map集合(原生的session被放到Map集合中了)
Map<String,Object> getApplication() -- 获取代表application域的Map集合
void put(String key,Object value) -- 注意:向request域中存入值 (没有getRequest,用起来反而不习惯了)
demo1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>demo1</title></head><body><h1>使用ActionContext类使用原生Servlet的API(方法一,完全解耦合)</h1><h3>注册页面</h3><form action="${ pageContext.request.contextPath }/demo1Action.action" method="post">姓名:<input type="text" name="username" /><br/>密码:<input type="password" name="password" /><br/><input type="submit" value="注册" /></form></body>
</html>
demo1Action.java ★
package cn.ahpu.action;import java.util.Arrays;
import java.util.Map;
import java.util.Set;import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;public class demo1Action extends ActionSupport {@Overridepublic String execute() throws Exception {//完全解耦合方式获取servlet的api进而前台数据ActionContext context = ActionContext.getContext();//先获取ActionContext//getParameters会封装所有的请求参数Map<String, Object> map = context.getParameters();//然后就可以通过context调用servlet的api获取数据了//拿到map所有key,再通过key遍历mapSet<String> keys = map.keySet();for (String key : keys) {//通过key获取值String[] vals = (String[]) map.get(key);System.out.println(key+" : "+Arrays.toString(vals));}//其他api使用演示context.getSession().put("msg", "Session成功!");context.getApplication().put("msg", "Application成功!");context.put("msg", "Resquest成功!");//直接put中间不写get默认getResquest了,因为太常用了,因此这么简单点设计return SUCCESS;}
}
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><package name="struts02" namespace="/" extends="struts-default"><action name="demo1Action" class="cn.ahpu.action.demo1Action"><result name="success">/demo1/suc.jsp</result></action><!-- 上两行决定了请求路径为 项目名/demo1Action.action 此处访问默认方法execute--></package>
</struts>
suc.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>sucess el表达式</title></head><body><h3>默认最小域(request)的msg:${msg }</h3><h3>requestScope:${requestScope.msg }</h3><h3>sessionScope:${sessionScope.msg }</h3><h3>applicationScope:${applicationScope.msg }</h3></body>
</html>
测试:
方法二、使用ServletActionContext类(原生Servlet的API的方式)(好用,掌握)★
jsp+servlet基础学得比较熟的,此方法比较简单直接,推荐
Struts2框架提供了一个类,ServletActionContext,该类中提供了一些静态的方法
具体的方法如下
getPageContext()
getRequest()
getResponse()
getServletContext()
可以直接获取未封装的原生的request/response等api,获取后用起来很顺手,用来接收或传递简单几个参数时很方便
demo1.jsp里加上
<h1>使用ServletActionContext类使用原生Servlet的API(方法二,比较简单顺手,常用)</h1><h3>注册页面</h3><form action="${ pageContext.request.contextPath }/demo2Action.action" method="post">姓名:<input type="text" name="username" /><br/>密码:<input type="password" name="password" /><br/><input type="submit" value="注册" /></form>
demo2Action.java
package cn.ahpu.action;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class demo2Action extends ActionSupport {private static final long serialVersionUID = 1L;@Overridepublic String execute() throws Exception {//似乎不封装数据 也默认会帮你放到session中 只要传递了HttpServletRequest request = ServletActionContext.getRequest();String name = request.getParameter("username");String pwd = request.getParameter("password");System.out.println("name:"+name+"\npwd:"+pwd);request.setAttribute("msg", "request值");request.getSession().setAttribute("msg", "session值");request.getServletContext().setAttribute("msg", "application值");//可还记得getServletContext()就是application//ServletActionContext.getServletContext().setAttribute("msg", "application值");//可以直接拿//找不到的api就写ServletActionContext. 根据提示肯定能找到HttpServletResponse response = ServletActionContext.getResponse();//response.getWriter().print("<br>response.getWriter打印值<br>");//一调用response.getWriter前端就乱码,所以不要这么用了 好不容易框架自动处理了乱码,可别给破坏了return SUCCESS;}
}
小插曲:页面的跳转result的配置总结
1. 结果页面存在两种方式
* 全局结果页面
> 条件:如果<package>包中的一些action都返回success,并且返回的页面都是同一个JSP页面,这样就可以配置全局的结果页面。
> 全局结果页面针对的当前的包中的所有的Action,但是如果局部还有结果页面,会优先局部的。使用的标签是
<global-results>
<result>/demo3/suc.jsp</result>
</global-results>
* 局部结果页面
<action ..>
<result>/demo3/suc.jsp</result>
</action ..>2. 结果页面的类型
* 结果页面使用<result>标签进行配置,包含两个属性
> name -- 逻辑视图的名称 就是匹配返回值
> type -- 跳转的类型,值一些,需要掌握一些常用的类型。常见的结果类型去struts-default.xml中查找。
* dispatcher -- 转发.默认值.Action--->JSP
* redirect -- 重定向.Action--->JSP
* chain -- 多个action之间跳转.Action---转发---Action
* redirectAction -- 多个action之间跳转.Action---重定向---Action
* stream -- 文件下载时候使用的
1.全局结果页面配置
删掉上例子中两个action中同样的result配置,外面加一个global-results
<global-results>
<result name="success">/demo1/suc.jsp</result>
</global-results><?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><package name="struts02" namespace="/" extends="struts-default"><!-- 下面两个action的跳转一模一样,删除,在外面配置一个全局的即可 --><global-results><result name="success">/demo1/suc.jsp</result></global-results><action name="demo1Action" class="cn.ahpu.action.demo1Action"><!-- <result name="success">/demo1/suc.jsp</result> --></action><action name="demo2Action" class="cn.ahpu.action.demo2Action"><!-- <result name="success">/demo1/suc.jsp</result> --></action></package> </struts>
依然正常运行,效果一样!
2.跳转类型设置
dispatcher
默认值 请求转发 action->jsp
修改(就是加个type="dispatcher")上例后 正常执行
redirect
重定向 action->jsp
改成转发,再次运行,request域中的值就传递不了了
redirectAction
重定向到Action Action->Action Action之间跳转路径不能写太详细 写匹配好的Action的name即可
演示重Demo3Action_save方法跳到Demo3Action_update
Demo3Action.java
package cn.ahpu.action;import com.opensymphony.xwork2.ActionSupport;public class Demo3Action extends ActionSupport {public String save() {System.out.println("save方法执行...");return "saveOK";}public String update() {System.out.println("update方法执行...");return NONE;}
}
struts.xml
<!-- 演示Action之间的跳转 注意:跳转路径写匹配好的Action的name即可--><action name="Demo3Action_*" class="cn.ahpu.action.Demo3Action" method="{1}"><result name="saveOK" type="redirectAction">Demo3Action_update</result></action>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>My JSP 'index.jsp' starting page</title></head><body><a href="${ pageContext.request.contextPath }/demo1/demo1.jsp">demo1</a><br><a href="${ pageContext.request.contextPath }/Demo3Action_save.action">Action之间跳转测试</a></body>
</html>
访问 ${ pageContext.request.contextPath }/Demo3Action_save.action
果然先执行save再执行update
暂时就演示3个
二、struts2专门的数据封装 ★
在Action类中写属性,提供get/set,框架自动帮你封装数据,还用得着啥子servlet api? 强大!!
1.属性驱动方式(封装到Action内定义的属性里)★
Action中定义属性 只用给属性添加set方法 然后框架的拦截器就自动帮你封装好了 属性name就是前端数据的name
demo2.jsp
<h3>属性驱动方式封装数据</h3><form action="${ pageContext.request.contextPath }/regist1.action" method="post">姓名:<input type="text" name="username" /><br/>密码:<input type="password" name="password" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="注册" /></form>
struts.xml
<!-- 新包 测试数据封装 一般一个项目一个包就够了 --><package name="demo2" namespace="/" extends="struts-default"><action name="regist1" class="cn.ahpu.action.Regist1Action"/></package>
Regist1Action.java
package cn.ahpu.action;import com.opensymphony.xwork2.ActionSupport;/*** 数据封装方式demo* 属性驱动*/
public class Regist1Action extends ActionSupport {//设置属性 只用给属性添加set方法 然后框架的拦截器就自动帮你封装好了,封装到了这些属性中private String username;private String password;private String age;public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;}public void setAge(String age) {this.age = age;}@Overridepublic String execute() throws Exception {System.out.println("name:"+username+"\n"+"pwd:"+password+"\nage:"+age);return NONE;}
}
2.属性驱动方式(封装到action的类成员变量里 前端要写OGNL麻烦 )(了解即可)
action内定义个属性,属性本身是个javabean 提供get/set 自己new不用提供set
demo2.jsp 注意name写法
<h3>属性驱动方式封装数据(Action内new一个javabean 直接封装到javabean对象中)</h3><form action="${ pageContext.request.contextPath }/regist2.action" method="post"><!-- 注意name写OGNL表达式 语法类似OGNL -->姓名:<input type="text" name="user.username" /><br/>密码:<input type="password" name="user.password" /><br/>年龄:<input type="text" name="user.age" /><br/><input type="submit" value="注册" /></form>
struts.xml
<action name="regist2" class="cn.ahpu.action2.Regist2Action"/>
User.java
package cn.ahpu.action2;public class User {private String username;private String password;private Integer age;//省略get set@Overridepublic String toString() {return "User [username=" + username + ", password=" + password+ ", age=" + age + "]";}}
Regist2Action.java
package cn.ahpu.action2;import com.opensymphony.xwork2.ActionSupport;/*** 数据封装方式demo* 属性驱动*/
public class Regist2Action extends ActionSupport {private User user=new User();//自己new了就不需要提供set了public User getUser() {return user;}@Overridepublic String execute() throws Exception {System.out.println(user);return NONE;}
}
3.模型驱动(前端name值不用写OGNL,也可封装到javaBean类对象中)★
模型驱动 最简单常用 实现一个接口 前端正常写 后端Action实例化一个javabean对象为属性 不需要get/set
模型驱动的方式
1.实现ModelDriven接口
2.手动实例化对象(需要自己new好)
前端demo2.jsp 写法没啥特殊之处了
<h3>属性驱动方式封装数据(模型驱动方式 不用改前端,也可封装数据到对象中)</h3><form action="${ pageContext.request.contextPath }/regist3.action" method="post">姓名:<input type="text" name="username" /><br/>密码:<input type="password" name="password" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="注册" /></form>
struts.xml
<action name="regist3" class="cn.ahpu.action2.Regist3Action"/>
User.java同上
Regist3Action.java
package cn.ahpu.action2;import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;/*** 数据封装方式demo* 模型驱动的方式* 1.实现ModelDriven接口2.手动实例化对象(需要自己new好)*/
public class Regist3Action extends ActionSupport implements ModelDriven<User>{private User user=new User();//必须自己new好//不用提供get/set 但必须实现这个方法 拦截器会调用这个必须实现的方法获取user对象,帮助你封装数据 多简单@Overridepublic User getModel() {return user;}@Overridepublic String execute() throws Exception {System.out.println("模型驱动"+user);return NONE;}}
4.数据封装到集合 list和map 能封装到List<User>和Map<String,User> 但是前端仍然要写OGNL,麻烦。不学了
三、拦截器
拦截器只能对Action请求起作用(Action中的方法),而过滤器可以对几乎所有的请求起作用(CSS JSP JS)
需要在struts.xml中进行拦截器的配置,配置一共有两种方式,学第一种即可
1.编写拦截器类,关键:继承
DemoInterceptor.java
package cn.ahpu.interceptor;import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class DemoInterceptor extends AbstractInterceptor {/*** 配置好后,执行action方法之前会执行intercept*/@Overridepublic String intercept(ActionInvocation invocation) throws Exception {System.out.println("Action方法执行之前");String invoke = invocation.invoke();//表示执行下一个拦截器(Struts2就是一大堆拦截器组成的) System.out.println("Action方法执行之后");return invoke;//返回值必须这么写 不放行就卡死在这了}}
2.编写一个新的action方法
UserAction.java
package cn.ahpu.action3;import com.opensymphony.xwork2.ActionSupport;public class UserAction extends ActionSupport{@Overridepublic String execute() throws Exception {System.out.println("我是UserAction的方法...");return NONE;}
}
3.配置拦截器(自定义拦截器,action引入自定义的拦截器) ★
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><package name="struts02" namespace="/" extends="struts-default"><!-- 下面两个action的跳转一模一样,删除,在外面配置一个全局的即可 效果:此struts02包下所有action的方法return success; 都会根据此配置跳转当然,若下面的action内还是自己配置了<result name="success"> 会覆盖掉全局的--><global-results><result name="success" type="redirect">/demo1/suc.jsp</result></global-results><action name="demo1Action" class="cn.ahpu.action.Demo1Action"><!-- <result name="success">/demo1/suc.jsp</result> --></action><action name="demo2Action" class="cn.ahpu.action.Demo2Action"><!-- <result name="success">/demo1/suc.jsp</result> --></action><!-- 演示Action之间的跳转 注意:跳转路径写匹配好的Action的name即可--><action name="Demo3Action_*" class="cn.ahpu.action.Demo3Action" method="{1}"><result name="saveOK" type="redirectAction">Demo3Action_update</result></action></package><!-- 新包 测试数据封装 一般一个项目一个包就够了 --><package name="demo2" namespace="/" extends="struts-default"><action name="regist1" class="cn.ahpu.action2.Regist1Action"/><action name="regist2" class="cn.ahpu.action2.Regist2Action"/><action name="regist3" class="cn.ahpu.action2.Regist3Action"/></package><!-- 新包,测试拦截器的使用 --><package name="demo3" namespace="/" extends="struts-default"><!-- package内action外定义拦截器--><interceptors><!-- name随便写 class必须是你写的那个Interceptor类的全路径 --><interceptor name="DemoInterceptor" class="cn.ahpu.interceptor.DemoInterceptor"/></interceptors><action name="user" class="cn.ahpu.action3.UserAction"><!-- 引入自定义拦截器 --><interceptor-ref name="DemoInterceptor"><!-- 放行写法 中间可以写写此不拦截的此action的方法--><!-- <param name="excludeMethods">login,regist,checkCode</param> --></interceptor-ref><!-- 只要引入了自定义拦截器,默认栈的拦截器就不执行了,必须手动引入 --><interceptor-ref name="defaultStack"/></action></package></struts>
4.测试运行
今日重点:
使用ServletActionContext类(原生Servlet的API的方式)(好用,掌握)★ [ServletActionContext.getRequest()]
属性驱动方式(封装到Action内定义的属性里)★ [Action内定义基本属性,提供get/set自动封装]
模型驱动(前端name值不用写OGNL,也可封装到javaBean类对象中)★ [Action实现ModelDriven接口,实现getModel]
拦截器★ [写Interceptor类实现接口,xml内先定义拦截器,再action内引入拦截器]
ssh备考-05Struts2 Action类下的重要API(原生Servlet的API、跳转配置、框架自身的数据封装、自定义拦截器)相关推荐
- ssh备考-02多表关联关系映射(一对一、一对多、多对多如何配置)
01搭建hibernate框架 02多表关联关系映射 03hibernate各种查询方式 目录 一.搭建环境 二.javabean和xml的基础配置 三.测试多表之间的关联配置效果 一对多级联保存: ...
- SSH整合中,使用父action重构子类action类.(在父类中获取子类中的泛型对象)
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;import com.opensymphony.xw ...
- ssh备考-08 SSH三大框架整合
可耻+可笑 救不活了的双非 算了,本来也就是过家家 目录 学习过程一步一步搭建框架,然后写需求 每次专注一个需求 每次最好也都自己搭建一次框架 可以照着文档模板复制粘贴 但是得自己搭建 一.新建项目 ...
- Struts2框架--学习笔记(下):OGNL表达式、值栈操作、拦截器、struts2标签、文件上传
一.OGNL概述:OGNL是一种表达式 (1)在struts2中操作值栈数据. (2)一般把ognl在struts2中操作,和struts2标签一起使用操作值栈. (3)ognl不是strut2的一部 ...
- java参数action_Struts2之Action接收请求参数和拦截器详解
技术分析之在Struts2框架中使用Servlet的API 1. 在Action类中也可以获取到Servlet一些常用的API 需求:提供JSP的表单页面的数据,在Action中使用Servlet的A ...
- Struts2之Action接收请求参数和拦截器
技术分析之在Struts2框架中使用Servlet的API 1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据, ...
- java中拦截这个类的方法_类拦截器和方法拦截器
一.拦截器 1.拦截器小介 拦截器的功能类似于web.xml文件中的Filter,能对用户的请求进行拦截,通过拦截用户的请求来实现对页面的控制.拦截器是在Struts-core-2.2.3.jar中进 ...
- Struts2的拦截器只允许有权限用户访问action
1.定义拦截器,继承MethodFilterInterceptor package com.life.stuts.interceptor;import java.util.Map;import com ...
- Android进阶:十三、自定义类加载器加载加密类文件
之前面试的时候有许多面试官问类加载器相关的问题,所以这是一个很重要的知识点.而且对于高级Android研发来讲,懂得更多类加载相关的东西,对开发也会有很多的帮助,比如热更新,类加密等. 其实笔者对类加 ...
最新文章
- Serverless 初体验:快速开发与部署一个Hello World(Java版)
- monty python喜剧-看美剧学托福:最受美国人喜欢的100部美剧
- Android:手把手教你 实现Activity 与 Fragment 相互通信(含Demo)
- 【Flutter】Animation 动画 ( Flutter 动画的核心类 | Animation | CurvedAnimation | AnimationController | Tween )
- 初学者Git和GitHub简介(教程)
- My_software_list
- deeplearning中卷积后尺寸的变化
- 中国农业种植施肥机械行业市场供需与战略研究报告
- qscoj:喵哈哈村的冒菜店(线段树区间合并)
- ISO8583报文格式分析
- 基于Java计算器 科学计算器与标准计算器相互转化
- Windows应用商店下载安装Ubuntu
- html5 判断页面加载,js判断页面是否加载完成的方法
- 不要说话 -- 陈奕迅/小柯
- Pycharm配置(1)——解释器(interpreter)
- C库函数——fabs()
- 使用for循环编写倒立反方向直角三角形
- 185电缆的接法图解_三相电缆线的接法图解
- 阿拉伯数字转韩文、中文
- 2016 清华 计算机 考研 经验 总结
热门文章
- 春节送礼经济学:绕不开的礼尚往来,怎么送礼最有效?
- Windows使用Docker出现exit 139错误
- GoLang 调用 .so 文件
- libpython3.7m so静态库_Python3.7:加载共享库时出错:libpython3.7m.so.1.0
- 记一次bro+pf_ring zc的搭建历程
- 《阿信》讲述了日本着名的百货连锁企业八佰伴创始人艰苦的过程
- MaxViT实战:使用MaxViT实现图像分类任务(一)
- 处理piv数字照相图位移matlab程序,PIV数字图像测试技术及在中间包水模实验中的应用...
- 一个Excel工具类
- Confluence 6 使用 LDAP 授权连接一个内部目录 - 用户 Schema 设置