Struts2
(在xml中,访问xml路径,默认在web下)
概述
应用javaee中的三层框架中的web层(展示层)
技术特点
原始的servlet:增加一个功能,就要添加一个servlet。
web时期用过baseServlet,反射实现
package com.yangwei.mvc.servlet;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 这个BaseServlet类不需要在web.xml中进行配置
*/
public class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* 所有的Servlet请求都会被service()方法拦截
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//传递过来用户的操作名(add,list,update等)即可
String mm=request.getParameter("operate");
Method method=this.getClass().getMethod(mm, HttpServletRequest.class,HttpServletResponse.class);
String rel=method.invoke(this, request,response);
String redirStr="redirect:";
if(rel.startsWith(redirStr)){
//客户端跳转
response.sendRedirect(rel.substring(redirStr.length()));
}else{
//将服务器端的跳转转移到这里统一执行
request.getRequestDispatcher("/WEB-INF/"+rel).forward(request,response);
}
}
}
servlet代码
package com.yangwei.mvc.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.yangwei.mvc.model.User;
/**
* 我们具体的Servlet继承BaseServlet
* 各个方法的返回值说明我们要跳转到的页面
*/
public class MyServlet extends BaseServlet {
public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("add method");
//对于客户端跳转,我们用redirect:标识
return "redirect:my/add.jsp";
}
public String update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("update method");
//服务器端的跳转
return "my/update.jsp";
}
public String delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("delete method");
//服务器端的跳转
return "my/delete.jsp";
}
}
要写到底层反射代码。
struts2如何解决?
所有的请求会被struts2自带的过滤器拦截,过滤器中对不同的操作,分别调用不同的方法去执行。
action:方法就写在action,类似之前的servlet方法
day01 Struts2入门
struts2的创建
首先是idea的配置,在这篇指导下完成 传送门
1、创建action(类似servlet),每次访问action的时候都会执行execute方法。
2、配置action类的访问路径
2.1 、创建核心配置文件,名称和位置是固定的。src下的 struts.xml
package
作用:类似于代码的包,用于区分不同的action。
标签的属性:
-
name : 和功能本身没有关系的,是为了用于区分不同的package
-
extend: 继承,固定为struts-default。类因此具备action功能
-
namespace:要和action标签里面的name值构成访问路径
action
作用:配置action的访问路径
标签的属性:
- name: 访问路径的一部分。同一个package下的action的name不可相同。
- class:全路径,为了反射时找到实体位置
- method:默认的是execute,假如现在希望执行的是update方法,那么method=“update”
result
作用:根据action的方法返回值,做跳转(不一定是页面,任何路径都行)
标签属性:
- name:和返回值进行匹配
- type: 配置跳转路径的方法,默认是转发(地址栏不变)
修改常量
最常用的一个,帮我们完善了post方式提交的中文乱码问题
目录如下
struts的执行过程
协调开发
struts配置文件中,可以通过引入的方式引入文件。
访问不同的action方法
1、在action的method属性标识
2、通配符实现(重点掌握)
struts2.5版本对此进行更新
需要把dtd约束改成2.5。
然后二选一
要么加上<global-allowed-methods>regex:.*</global-allowed-methods>
要么加上<allowed-methods>add,hello</allowed-methods>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="hellodemo" extends="struts-default" namespace="/">
<!--访问hello_update 那么就执行update方法
{1}标识第一个*
-->
<global-allowed-methods>regex:.*</global-allowed-methods>
<action name="User_*" class="com.lin.struts.StrutsDemo" method="{1}">
<result name="success">/hello.jsp</result>
<allowed-methods>add,hello</allowed-methods>
</action>
</package>
</struts>
3、动态访问
day02 Struts2入门 数据操作
1、结束页面配置
全局加局部,局部优先级大
1.1 全局结果页面
作用:多个action,返回的是用一个结果页面
配置:在package中!
只在当前package中生效
1.2 局部结果页面(普通)
<package name="demo" extends="struts-default" namespace="/">
<global-results>
<result name="success">/quanju.jsp</result>
</global-results>
<action name="Login" class="com.lin.action.LoginAction">
<result name="success">/login.jsp</result>
</action>
<action name="Regist" class="com.lin.action.RegistAction">
<!--<result name="success">/regist.jsp</result>-->
</action>
</package>
1.3 result中的type属性
- 重定向 redirect
- 转发 dispatcher
到其他action
- chain:转发到action 一般不用
- redirectAction: 重定向到action
2、在action获取表单提交的数据
2.1 使用ActionContext类获取
2.2 使用ServletActionContext类获取操作域对象
2.3 使用接口的注入方式获取
3、在struts2里面使用的封装方式
3.1 属性封装
在action中定义数据成员(和表单一一对应且name相等,当表单发送过来时,struts2自动把数据封装到数据成员中)
3.2 模型驱动封装(主要使用)
第一步:action实现ModelDriven
第二步:new一个实体类的对象
第三步:在getModel中返回该对象
第四步:操作该对象
作用:
当表单发送数据过来时,自动封装到这个对象里面
3.3 表达式封装(适合封装到不同的实体类)
第一步:在action里声明实体类
第二部:生成实体类对象的get、set方法
第三步:在表单输入项的name属性值里面写表达式形式
4、获取数据封装到集合中(会用)
4.1 封装到list
4.2 封装到map
5、实战,客户关系系统中的添加客户
第一步: 通过模型驱动完成表单获取
第二步:使用hibernate插入新数据
第三步:发送请求至查询页面,展示新插入的数据
day03 Struts2的值栈和ognl表达式
1、OGNL表达式
1.1 简介
之前在web阶段学习过EL表达式,应用在JSP页面中获取域对象内容
用于struts2里面操作值栈数据,可以结合struts2里面的标签一起使用值栈
ognl不属于struts2的一部分,他是单独存在的。struts2提供了ognl的jar包
1.2 ognl入门实例
第一步:导入jar包,然后引入标签库
之前在使用jstl的时候需要引入标签库,现在也一样,第一步是引入标签库
第二步:结合struts的标签
2、值栈
我们之前把东西放到作用域中,现在可以用struts2提供值栈来存取数据。
2.1 servlet和action的区别
-
servlet只在第一次访问的时候创建,创建一次,单实例
-
action每次访问的时候,创建action
2.2 值栈存储位置
每次访问都会创建action,每个action对象拥有独立的一个值栈
2.2 获取值栈对象
方法一: 用ActionContext对象获取
方法二
2.3 值栈内部结构
第一部分:root,结构是list集合(一般使用这个)
第二部分: context,结构是map