Struts2之Action接收请求参数和拦截器
技术分析之在Struts2框架中使用Servlet的API
1. 在Action类中也可以获取到Servlet一些常用的API
* 需求:提供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>
2. 完全解耦合的方式
* 如果使用该种方式,Struts2框架中提供了一个类,ActionContext类,该类中提供一些方法,通过方法获取Servlet的API
* 一些常用的方法如下
* static ActionContext getContext() -- 获取ActionContext对象实例
* java.util.Map<java.lang.String,java.lang.Object> getParameters() -- 获取请求参数,相当于request.getParameterMap();
* java.util.Map<java.lang.String,java.lang.Object> getSession() -- 获取的代表session域的Map集合,就相当于操作session域。
* java.util.Map<java.lang.String,java.lang.Object> getApplication() -- 获取代表application域的Map集合
* void put(java.lang.String key, java.lang.Object value) -- 注意:向request域中存入值。
3. 使用原生Servlet的API的方式(常用到)
* Struts2框架提供了一个类,ServletActionContext,该类中提供了一些静态的方法
* 具体的方法如下
* getPageContext()
* getRequest()
* getResponse()
* getServletContext()
技术分析之结果页面的跳转
1. 结果页面存在两种方式
* 全局结果页面
> 条件:如果<package>包中的一些action都返回success,并且返回的页面都是同一个JSP页面,这样就可以配置全局的结果页面。
> 全局结果页面针对的当前的包中的所有的Action,但是如果局部还有结果页面,会优先局部的。使用的标签是
<global-results>
<result>/demo3/suc.jsp</result>
</global-results>
* 局部结果页面
<result>/demo3/suc.jsp</result>
2. 结果页面的类型
* 结果页面使用<result>标签进行配置,包含两个属性
> name -- 逻辑视图的名称
> type -- 跳转的类型,值一些,需要掌握一些常用的类型。常见的结果类型去struts-default.xml中查找。
* dispatcher -- 转发.type的默认值.Action--->JSP
* redirect -- 重定向. Action--->JSP
* chain -- 多个action之间跳转.从一个Action转发到另一个Action. Action---Action
* redirectAction -- 多个action之间跳转.从一个Action重定向到另一个Action. Action---Action
* stream -- 文件下载时候使用的
技术分析之Struts2框架的数据封装
1. 为什么要使用数据的封装呢?
* 作为MVC框架,必须要负责解析HTTP请求参数,并将其封装到Model对象中
* 封装数据为开发提供了很多方便
* Struts2框架提供了很强大的数据封装的功能,不再需要使用Servlet的API完成手动封装了!!
2. Struts2中提供了两类数据封装的方式?
* 第一种方式:属性驱动
> 提供对应属性的set方法进行数据的封装。
* 表单的哪些属性需要封装数据,那么在对应的Action类中提供该属性的set方法即可。
* 表单中的数据提交,最终找到Action类中的setXxx的方法,最后赋值给全局变量。
* 注意0:Struts2的框架采用的拦截器完成数据的封装。
* 注意1:这种方式不是特别好:因为属性特别多,提供特别多的set方法,而且还需要手动将数据存入到对象中.
* 注意2:这种情况下,Action类就相当于一个JavaBean,就没有体现出MVC的思想,Action类又封装数据,又接收请求处理,耦合性较高。
> 在页面上,使用OGNL表达式进行数据封装。
* 在页面中使用OGNL表达式进行数据的封装,就可以直接把属性封装到某一个JavaBean的对象中。
* 在页面中定义一个JavaBean,并且提供set方法:例如:private User user;
* 页面中的编写发生了变化,需要使用OGNL的方式,表单中的写法:<input type="text" name="user.username">
* 注意:只提供一个set方法还不够,必须还需要提供user属性的get和set方法!!!
> 先调用get方法,判断一下是否有user对象的实例对象,如果没有,调用set方法把拦截器创建的对象注入进来,
/**
* 属性驱动方式,把数据封装到JavaBean的对象中
* @author Administrator
*/
public class Regist2Action extends ActionSupport{ private static final long serialVersionUID = 6556880331550390473L; // 注意二:属性驱动的方式,现在,要提供是get和set方法
private User user;
public User getUser() {
System.out.println("getUser...");
return user;
}
public void setUser(User user) {
System.out.println("setUser...");
this.user = user;
} public String execute() throws Exception {
System.out.println(user);
return NONE;
} }
* 第二种方式:模型驱动
> 使用模型驱动的方式,也可以把表单中的数据直接封装到一个JavaBean的对象中,并且表单的写法和之前的写法没有区别!
> 编写的页面不需要任何变化,正常编写name属性的值
> 模型驱动的编写步骤:
* 手动实例化JavaBean,即:private User user = new User();
* 必须实现ModelDriven<T>接口,实现getModel()的方法,在getModel()方法中返回user即可!!
/**
* 模型驱动的方式
* 实现ModelDriven接口
* 必须要手动实例化对象(需要自己new好)
* @author Administrator
*/
public class Regist3Action extends ActionSupport implements ModelDriven<User>{ private static final long serialVersionUID = 6556880331550390473L; // 必须要手动实例化
private User user = new User();
// 获取模型对象
public User getModel() {
return user;
} public String execute() throws Exception {
System.out.println(user);
return NONE;
} }
技术分析之Struts2把数据封装到集合中
1. 封装复杂类型的参数(集合类型 Collection 、Map接口等)
2. 需求:页面中有可能想批量添加一些数据,那么现在就可以使用上述的技术了。把数据封装到集合中
3. 把数据封装到Collection中
* 因为Collection接口都会有下标值,所有页面的写法会有一些区别,注意:
<input type="text" name="products[0].name" />
* 在Action中的写法,需要提供products的集合,并且提供get和set方法。
4. 把数据封装到Map中
* Map集合是键值对的形式,页面的写法
<input type="text" name="map['one'].name" />
* Action中提供map集合,并且提供get和set方法
代码:
/**
* 属性驱动的方式,把数据封装到map集合中
* @author Administrator
*/
public class Regist5Action extends ActionSupport{ private static final long serialVersionUID = 6556880331550390473L; private Map<String, User> map;
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
} public String execute() throws Exception {
System.out.println(map);
return NONE;
} }
案例总结之Struts2的拦截器技术
1. 拦截器的概述
* 拦截器就是AOP(Aspect-Oriented Programming)的一种实现。(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。)
* 过滤器:过滤从客服端发送到服务器端请求的
* 拦截器:拦截对目标Action中的某些方法进行拦截
* 拦截器不能拦截JSP
* 拦截到Action中某些方法
2. 拦截器和过滤器的区别
1)拦截器是基于JAVA反射机制的,而过滤器是基于函数回调的
2)过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器
3)拦截器只能对Action请求起作用(Action中的方法),而过滤器可以对几乎所有的请求起作用(CSS JSP JS)
* 拦截器 采用 责任链 模式
> 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链
> 责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行
* 在struts2 中可以定义很多个拦截器,将多个拦截器按照特定顺序 组成拦截器栈 (顺序调用 栈中的每一个拦截器 )
3. Struts2自带的拦截器
- Exception : 异常处理机制拦截器
- i18n : 处理中文问题
- modelDriven : 将请求参数,封装model对象 (Action 实现ModelDriven接口)
- fileUpload :文件上传
- params : 请求参数转换封装
- conversionError : 将类型转换异常进行处理
- validation : 请求参数校验
- workflow : 判断fieldError 是否存在,如果存在,自动跳转input视图
4. Struts2的核心是拦截器,看一下Struts2的运行流程
自定义拦截器和配置
用户登录(用户信息保存到session中),如果登录可以访问BookAction中的方法
1. BookAction代码:
public class BookAction extends ActionSupport { private static final long serialVersionUID = 1L;
public String add(){
System.out.println("添加图书");
return NONE;
}
public String delete(){
System.out.println("删除图书");
return NONE;
}
}
2.定义拦截器,控制如果用户未登陆,无法访问BookAction
public class LoginInterceptor extends MethodFilterInterceptor {
private static final long serialVersionUID = 1L; protected String doIntercept(ActionInvocation invocation) throws Exception {
//判断用户是否登录
if(ServletActionContext.getRequest().getSession().getAttribute("user")==null){
return "input";
}else{
//执行像一个方法
return invocation.invoke();
}
}
}
3. 需要在struts.xml中进行拦截器的配置,配置一共有两种方式
<struts>
<!-- 开启开发者模式 -->
<constant name="struts.devMode" value="true"></constant>
<package name="login" namespace="/" extends="struts-default">
<interceptors>
<!-- 拦截器 名=实现类 映射 -->
<interceptor name="loginI" class="cn.it.ation.LoginInterceptor"/>
<!-- 拦截器栈处理 取名 随便 望文生义 -->
<interceptor-stack name="loginStack">
<interceptor-ref name="defaultStack"/>
<!--通过拦截器名 找到实现类 : 配置 参数 不拦截的方法 -->
<interceptor-ref name="loginI">
<!-- 你想拦截的方法-->
<param name="includeMethods">add,delete</param>
<!-- 排除在外的方法
<param name="excludeMethods">login</param>-->
</interceptor-ref>
</interceptor-stack>
</interceptors> <!-- 对所有Action生效 -->
<default-interceptor-ref name="loginStack"/>
<action name="user_*" class="cn.it.ation.UserAction" method="{1}">
<result name="success">/welcome.jsp</result>
<result name="input">/login.jsp</result>
</action>
<action name="book_*" class="cn.it.ation.BookAction" method="{1}">
<result name="input">/login.jsp</result><!--配置跳转视图 -->
</action>
</package>
</struts>
Struts2之Action接收请求参数和拦截器的更多相关文章
- Struts系列笔记(6)---action接收请求参数
action接收请求参数 在web开发中,去接收请求参数来获得表单信息非常的常见,自己也总结整理了有关Struts2通过action接收请求参数的几种方法. Struts2 提供三种数据封装的方式: ...
- Struts框架(6)---action接收请求参数
action接收请求参数 在web开发中,去接收请求参数来获得表单信息非常的常见,自己也总结整理了有关Struts2通过action接收请求参数的几种方法. Struts2 提供三种数据封装的方式: ...
- struts2 action接收请求参数和类型转换
1,action接收请求参数 在struts2中action是什么?(struts2是一个mvc框架) V:jsp M:action C:action ...
- action接收请求参数
一.采用基本类型接收请求参数(get/post)在Action类中定义与请求参数同名的属性,struts2便能接收自动接收请求参数并赋给同名属性. action的代码: public class Pa ...
- Struts2中action接收中文参数为乱码解决方法
老实说,中文乱码问题是每个程序员会经常遇到的问题,而且也是一个很头疼的问题.网上很多关于解决中文乱码的帖子,看几个之后你会发现大都是一样的.但是我们照着做,却还是无法解决乱码问题.我也是看了好多帖子, ...
- struts2之Action获取请求参数与web元素
文章思路清晰 http://blog.csdn.net/zeqblog/article/details/8665052
- Struts2笔记2--动态方法调用和Action接收请求方式
动态方法调用(在请求的时候,再明确具体的响应方法,配置的时候不明确): LoginAction类中有两个方法some和second 1. 动态方法的调用(修改常量struts.enable.Dynam ...
- Struts2中Action接收参数的方法主要有以下三种:
Struts2中Action接收参数的方法主要有以下三种: 1.使用Action的属性接收参数(最原始的方式): a.定义:在Action类中定义属性,创建get和set方法: b.接 ...
- Struts2基础-3 -继承ActionSupport接口创建Action控制器+javaBean接收请求参数+ 默认Action配置处理请求错误 + 使用ActionContext访问ServletAPI
1.目录结构及导入的jar包 2.web.xml 配置 <?xml version="1.0" encoding="UTF-8"?> <web ...
随机推荐
- (5)java中的常用API,其实就是一些常见类的使用
String方法来介绍 两种声明: 1.String str="1";这种首先检查常量池中是否已经有该常量字符串"1" 如果有的话,不会创建新的常量字符串,若有 ...
- 分离数据库时出错:无法对数据库'XXX' 执行删除,因为它正用于复制"的解决方法
出现的原因是要分离的数据库是一个发布订阅的数据库.因为正在复制,所以无法脱机. 解决办法是停止发布订阅,或者删掉它..再分离.有部分情况是在复制目录下并没有看到发布订阅. 有可能是因为以前建立发布订阅 ...
- Halloc内存分配器
MAX_NSBS 8192:默认的最大superblocks数量 SB_SET_SZ(MAX_NSBS / WORD_SZ):superblock set的大小,每个set32个superblcoks ...
- Android Studio开发遇到程序崩溃问题
在用Android Studio开发过程中,经常遇到程序本身没有错误,但运行起来却总是挂掉,具体有如下几个解决方案: 1.将运行在真机上的app卸载,重新运行安装 2.在Build选项中有一个clea ...
- scipy安装问题
刚开始使用pip安装的scipy,后来报了错误,具体意思是 numpy版本不支持. 在python.org.pypi 官网上的SciPy包是一个zip版本的,要使用与numpy相对应的后缀才行,也就 ...
- Swift应用案例 2.闭包入门到精通
本文主要介绍Swift的闭包的使用并与OC的Block做比较.学习Swift是绕不过闭包的,因为无论是全局函数还是嵌套函数都是闭包的一种,本文主要介绍闭包表达式. 1.闭包表达式的使用 // 1. ...
- Tcl与Design Compiler (九)——综合后的形式验证
本文属于原创手打(有参考文献),如果有错,欢迎留言更正:此外,转载请标明出处 http://www.cnblogs.com/IClearner/ ,作者:IC_learner 这里来讲一下forma ...
- java封装的方法
java封装是由Java是面向对象程序设计语言的性质决定的,面向对象程序设计语言的三大特性之一就是封装.封装其实就是包装的意思,从专业的角度来看,就是把对象的所有组成部分组合在一起,保护私有属性. 如 ...
- 分布式统一配置平台-Disconf.Net
源码地址:https://github.com/qkbao/Disconf.Net 作者:青客宝 联系qq:后续奉上 为了更好的解决分布式环境下多台服务实例的配置统一管理问题,本文提出了一套完整的分 ...
- C#调用webbrowser,阻止弹出新IE窗口
本人是用WPF内嵌 winform的webbrowser这种形式开发, 弹出的 //屏蔽弹出新IE窗口 private void webBrowser_NewWindow(object sender, ...