用户登录:
1.登录-->登录的请求--->用户名、密码
2.后台处理请求-->用户填写信息校验
1.true:首页
2.false:失败界面
2_1:在strust获取用户输入
1.通过action的属性获取
2.使用领域对象(封装成javabean对象)
3.使用Struts2中提供的拦截器将数据注入进来,action实现ModelDriven接口即可(推荐使用)
2_2:action的编写方式
1.直接定义Class
2.继承ActionSupport(推荐):ActionSupport implements Action, Validateable(使用输入校验)
3.实现Action接口
2_4:构建BaseAction
1.strust的执行流程
1.发起请求-->url地址--->经过struts的前端控制
2.通过url地址查询struts.xml文件中看那个action和它匹配
3.调用该action中的方法返回逻辑视图名
4.回到struts.xml中该action的位置查询与返回值相同的result节点,最终返回指定的视图里面
/ login
struts2中的url地址的构成:namespace+actionName
下午:
0.Servlet的解耦:不依赖与Servlet容器,
0:在软件开发中模块与模块之间关系是否密切是通过耦合度来衡量的。如果A模块对B模块的依赖较高说明A模块和B模块的耦合度高,一旦B模块发生变化就会影响A模块。
1.用户登录之后成功界面上显示用户名
ActionContext context = ActionContext.getContext();
Map<String, Object> session = context.getSession();//对应session
session.put("s1", "这个session中的数据");
Map<String, Object> application = context.getApplication();//对应application域
application.put("a1", "这个application中的数据");
context.put("user", user);//将数据放到request域中--->result默认请求转发的
//HttpServletRequest等是由Servlet Api提供的
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext servletContext = ServletActionContext.getServletContext();
2. Strut2提供aware的接口,让strus注入进来
1.RequestAware--->注入Map类型的request对象
2.SessionAware--->注入Map类型的session对象
3.ApplicationAware--->注入Map类型的Application对象
4.ServletReqeustAware-->注入原始的HttpServletRequest对象
5.ServletContextAware-->注入原始的ServletContext对象
3.Struts中通过ActionContext对象以及RequestAware、SessionAware、ApplicationAware来实现与Servlet的解耦
1.方法统配符:*-->通过url地址来确定调用的方法
1.思考?如何处理用户的添加、删除、修改操作
<!--
/ UserAction_deleteUser
method="{1}":去第一个*的值
*_*:去值{N}:n从1开始,多个*之间最好还是加上分隔符
如果n=0,表示整个Url地址
{0}:UserAction_deleteUser
-->
<action name="UserAction_*" class="com.woniu.struts2.action.UserAction" method="{1}">
<result name="success">/success.jsp</result>
<result name="fail">/fail.jsp</result>
</action>
2.动态方法调用:官网明确,不推荐使用 ! actionName!actionMethod.action
2.方法校验--->Validateable接口提供的功能
0.用户注册--->验证数据的合法性(密码不能为空,并且大于6位)?
1.全方法校验
//重写validate设置自己的校验规则
@Override
public void validate() {
if(user.getPassword()!=null&&user.getPassword().length()>=6){//数据是合法的
//校验成功
}else{
//校验失败--->?标识
//addActionError(anErrorMessage);//标识校验失败
//addFieldError(fieldName, errorMessage);//那个属性校验失败
addActionError("密码不合法");//---->默认返回到逻辑视图名为input的视图
}
}
2.指定方法校验
//指定方法校验,validateXXX:xxx方法名 首字母大写
public void validateRegister() {
if(user.getPassword()!=null&&user.getPassword().length()>=6){//数据是合法的
//校验成功
}else{
//校验失败--->?标识
//addActionError(anErrorMessage);//标识校验失败
//addFieldError(fieldName, errorMessage);//那个属性校验失败
addActionError("密码不合法");//---->默认返回到逻辑视图名为input的视图
}
}
3.Action中几个常量
4.流程-->执行调用的方法之前执行校验方法(validate),通过addActionError,addFieldError方法来标识校验失败,一旦校验失败之后跳转逻辑视图名为input的视图。
校验成功继续调用想调用的方法
2.23
上午
1.配置文件:
0.Struts前端控制器-->filter---->
init方法默认读取三类的文件:struts.xml(配置文件:开发人员需要关注的文件)、struts-plugin.xml(插件)、struts-default.xml(默认的配置文件)、struts.properties(配置信息)
内容:
1.常量-->core包里面的default.properties中查看
0:struts.i18n.encoding:国籍化
1.action的扩展名:struts.action.extension,默认使用的action后缀,请求的后缀只能在配置文件进行修改,不能再web.xml文件进行修改
2.struts.devMode:在项目开发阶段设置true,有更加详细的日志信息
3.struts.ui.theme:主题
4.struts.multipart.maxSize:文件上传的最大值(默认为2097152byte)
5.struts.configuration.xml.reload:一旦修改struts.xml文件就自动加载
2.package:等同于java中package--->管理所有的action的
1.属性
name:作用不大,只用于继承
namespace:命名空间,该package的唯一标识,必须的
extends:该package继承至那个package
abstract:只能由于继承,该package不能有action
3.action:对应struts中action的配置
1.属性
name:该action的名称,具有唯一性
class:该action所对应的class的全限定名
method:调用该action中的那个方法
2.默认action及默认方法
当class属性没写:默认执行的action是ActionSupport
当method没写:默认执行的该action的中execute方法
4.result:视图-->逻辑视图名和真实的视图的一一对应的关系
1.属性
name:逻辑视图名,和action中返回的string类型的值相等,默认值为success
type:返回的视图的类型
1.dispatcher:以转发的形式返回,默认的type类型
2.plainText:以文本的形式返回视图
3.stream:以流的形式返回数据,多用于文件下载
4.redirect:重定向
5.redirectAction:重定向到指定的action中
需求:删除操作?先通过id进行删除,再重定向到list界面
<!-- 重定向到其他的namespace -->
<result name="ddd" type="redirectAction">
<param name="namespace">/my</param>
<param name="actionName">UserAction_index.go</param>
</result>
<!-- 重定向到相同的namespace -->
<!-- <result name="ddd" type="redirectAction">UserAction_index.go</result> -->
2.全局视图:
<!-- 全局视图:对该包中的所有的action都是有效 -->
<global-results>
<result name="error">/error.jsp</result>
</global-results>
5.include:引入外部的struts的配置文件
2.拦截器(核心)--->优先于action执行
0.--->用户登录过滤
1.自定义拦截器--->实现Interceptor接口
1. 实现Interceptor接口
2. 在struts.xml文件进行配置拦截器
3. 使用
1.只针对某个action有效,在该action的节点下使用<interceptor-ref
2.所有的action都是有效的--->包含struts默认的拦截器栈
下午
1.文件上传、文件下载
1.1文件上传
1.添加依赖:io、fileUpload
2.返回json数据--->json的插件--->自定义列一个resultType
1.引入struts2-json-plugin插件
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.29</version>
</dependency>
2.让package继承json-default
<package name="default" namespace="/" extends="struts-default,json-default">
3.result指定type为json
<!-- 返回json数据 -->
<result name="json" type="json">
<!-- 待转换的json数据的来源:action中的属性 -->
<param name="root">users</param>
<param name="encoding">UTF-8</param>
</result>
3.数据类型转换器
1、编写自定义类型转换器类extends defaulttypeconverter
2、将上面的类型转换器注册为局部类型转换器:指定的action有效
在Action类所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是Action的类名,后面的-conversion.properties是固定写法,对于本例而言,文件的名称应为HelloWorldAction-conversion.properties 。在properties文件中的内容为:
属性名称=类型转换器的全类名
对于本例而言, HelloWorldAction-conversion.properties文件中的内容为:
createtime= cn.itcast.conversion.DateConverter
3、将上面的类型转换器注册为全局类型转换器:全局的
在WEB-INF/classes(及src)下放置xwork-conversion.properties文件 。在properties文件中的内容为:
待转换的类型=类型转换器的全类名
对于本例而言, xwork-conversion.properties文件中的内容为:
java.util.Date= cn.woniuxy.conversion.DateConverter
4.标签库
iterator标签中的status属性,迭代时iterator会将值压入栈(值栈)顶,使用<s:property />可以直接输出
#status.odd 是否奇数行
#status.count 当前行数
#status.index 当前行的序号,从0开始[#status.count=#status.index+1]
#status.first 是否第一行
#status.last 是否最后一行
#status.modules(int) 当前行数取模
<select标签 list为action中对应的list listkey属性为提交的值 默认的listkey和listvalue的数据类型是string
5.ognl表达式
如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
application对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
放入request范围的数据在struts.xml文件中使用el表达式能获取到值如:${#request.fileName}还得注意乱码的问题
parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
attr对象:用于按page->request->session->application顺序访问其属性。
<s:iterator value="persons.{?#this.age=21}"><!-- 对persons这个集合进行迭代筛选出符合要求的所有对象,jsp中要访问对象的属性则类中必须提供get方法 -->
2.源码分析
1.前端控制器-->StrutsPrepareAndExecuteFilter-->filter-->生命周期
0. init(servlet容器启动之后调用)-->doFilter(请求到来)-->destroy