Struts
tomcat:8.5
1)struts初步了解
什么是框架:
框架简单的来说就是一个半成品的项目,用了框架之后
我们会更快,更好的完成项目.
什么是struts:
struts2是处理访问服务器的请求
取代servlet
struts下载
2)使用传统servlet编写用户登录功能
3)使用struts2编写用户登录功能
4)对比两种方式
5)学习struts2(重点)
struts.xml ----书写Action
–书写struts.xml
–核心配置
–动态方法调用
–结果集的处理
–转发
–重定向
–转发到Action
–重定向到Action
参数传递 --接收参数
–传递参数–jsp,action
–ActionContext
ognl–jstl+el — <s:iterator value=“pasteList” var=“paste”></s:iterator>
<s:property value=“ansnum” />
如果要访问的数据是包装类型,我们要加#
<s:property value="#user.username"/>
<s:if test=“ansnum%2==0”></s:if>
<s:else></s:else>
valueStack
action原理
result原理
拦截器 --创建拦截器的两种方式
--配置拦截器(拦截器只能控制访问Action,不能控制访问jsp)
用户登录
查看所有帖子
struts2的Filter的配置:
在web.xml中:记住这个启动的类名完整路径org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
<filter>
<filter-name>struts2</filter-name>
<!-- 记住这个启动的类名完整路径org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter-->
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置struts.xml(放在src文件下):前面这部分是必须的
<?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表示包名,namespace表示在浏览器输入地址时的前面部分,localhost:8080/+namesapce+<action>标签中的name -->
<package name="hello" namespace="/" extends="struts-default">
<!-- name 输入进网址的名称路径 class 就是这个Action的完整路径 method:需要调用的方法 -->
<action name="HelloAction" class="com.rabbit.web.HelloAction" method="execute">
<!-- result 如果执行方法返回 的值等于result标签中的值,那么转发到index.jsp中 -->
<!-- 默认为转发 这里我们改成重定向 -->
<result name="success" type="redirect">/index.jsp</result>
</action>
</package>
</struts>
struts配置log4j:https://blog.csdn.net/lzhat/article/details/53687477
使用Action替代Servlet:
- 需要继承ActionSupport;
- 重写excute()方法;
- 从表单获取username和password封装成User类需要继承ModelDriven<>接口 ,泛型中写上需要封装成的类,重写getModel()方法;得到user对象;
代码演示:
public class HelloAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
private UserService service = new UserService();
@Override
public String execute() throws Exception {
boolean success = service.findUser(user);
if(success) {
return "success";
}else {
//如果用户名密码错误,得到request向设置信息
ServletActionContext.getRequest().setAttribute("msg", "用户名或密码错误");
return "error";
}
}
@Override
public User getModel() {
return user;
}
}
Servlet和Struts2的区别:
-
启动
- Servlet:配置xml中Servlet标签或者使用注解
- Struts2:配置web.xml,filter标签
-
创建:
-
Servlet:继承HttpServlet,重写doget(),doPost()方法
-
struts:继承ActionSupport;配置struts.xml文件;
<?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表示包名,namespace表示在浏览器输入地址时的前面部分,localhost:8080/+namesapce+<action>标签中的name --> <package name="hello" namespace="/" extends="struts-default"> <!-- name 输入进网址的名称路径 class 就是这个Action的完整路径 method:需要调用的方法 --> <action name="HelloAction" class="com.rabbit.web.HelloAction" method="execute"> <!-- result 如果执行方法返回 的值等于result标签中的值,那么转发到index.jsp中 --> <!-- 默认为转发 这里我们改成重定向 --> <result name="success" type="redirect">/main.jsp</result> <result name="error" >/index.jsp</result> </action> </package> </struts>
-
-
封装数据:
- Servlet:使用request.getParamterMap()或者getParmater()获取表单的参数,再使用BeanUtils封装
- struts:继承ModelDriven接口,泛型中写上需要封装成的domain类,重写getModel()方法得到T的对象(需要先在Action中创建domain成员变量 private User user = new User(););
-
转发与重定向:
- Servlet:
- 转发:request.getRequestDispatcher(“path”).forward(request,response);
- 重定向:response.sendRedirect(“path”)
- Struts:**在struts.xml文件中配置result标签的type属性,默认是转发,可以不写。重定向:type=“redirect”;**在result标签中写上path值;
- Servlet:
实现Action的三种方式:
- **(常用)**继承ActionSupport类,struts.xml中配置
- 直接写一个类交xxxAction,struts.xml中配置
- 实现一个com.opensymphony.xwork2.Action接口,struts.xml中配置
配置struts.xml:
-
核心配置:
- 标签package:
- name:用于区分package;namespace:命名空间;extends=“struts-default”;
- 标签action:
- name:命名。class=“完整类名” method=“调用的方法”;
- 标签package:
-
动态方法调用:使用通配符regex:.*
- struts.xml配置:
首先在struts标签下配置:
<constant name="struts.deMode" value="true"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
在package标签下写上通配符,需要动态调用的方法:
<!-- 通配符 -->
<global-allowed-methods>execute,register</global-allowed-methods>
在action标签中写上通配符名称+_*,method={1}
<action name="HelloAction_*" class="com.rabbit.web.HelloAction" method="{1}">
* 动态方法调用完整演示:
<?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>
<!-- 动态方法调用 -->
<constant name="struts.deMode" value="true"></constant>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<!-- package中的 name表示包名,namespace表示在浏览器输入地址时的前面部分,localhost:8080/+namesapce+<action>标签中的name -->
<package name="hello" namespace="/" extends="struts-default">
<!-- 通配符 -->
<global-allowed-methods>execute,register</global-allowed-methods>
<!-- name 输入进网址的名称路径 class 就是这个Action的完整路径 method:需要调用的方法 -->
<action name="HelloAction_*" class="com.rabbit.web.HelloAction" method="{1}">
<!-- result 如果执行方法返回 的值等于result标签中的值,那么转发到index.jsp中 -->
<!-- 默认为转发 这里我们改成重定向 -->
<result name="success" type="redirect">/main.jsp</result>
<result name="error" >/index.jsp</result>
</action>
<action name="DefaultAction" class ="com.rabbit.web.DefaultAction" method="hello">
<result name="hello"></result>
</action>
<action name="ImpAction" class="com.rabbit.web.ImpAction" method="execute"></action>
</package>
</struts>
- 结果集处理:转发和重定向到页面跟前面的一样,默认转发,重定向写上type属性=“redirect”
-
转发到Action: type=“chain”,在在reslut中配上转发到的Action名称
-
重定向到Action: type="redirectAction"在在reslut中配上转发到的Action名称或者名称加方法。
-
结果集处理转发重定向到Action代码演示:
<action name="ImpAction" class="com.rabbit.web.ImpAction" method="execute"> <!-- 转发到DefaultAction --> <result name="toDefaultAction" type="chain">DefaultAction</result> <!-- 重定向到HelloAction_register --> <result name="toHello" type="redirectAction">HelloAction_register</result> </action>
-
全局结果集(当前包下的所有结果集都有它):
<global-results> <result name="toLogin" type="redirect">/index.jsp</result> </global-results>
-
参数传递:
- 接收参数:
- 第一种(常用):就是实现ModelDriven<>接口,重写getModel方法(先穿件User成员变量)
- 第二种:直接写上参数成员变量:private String username ; private String password;生成这两个参数的get set方法。直接给User对象set参数
- 第三种:写上User的成员变量,不new出来;::private User user;生成user的getset方法,在jsp文件中把name属性改为:user.username;user.password;
- 传递参数:传递到jsp或者action;依赖ActionContext,它是一个Map;
-
ActionContext里面有想要的所有东西:request,response,ServletContext,request域,session域,application域。response域等等;
-
ActionContext的生命周期,每次请求都会创建一个对应的ActionContext对象,请求结束就销毁对象;
-
传递参数的yzm案例演示:
public void yzm() throws IOException { BufferedImage image = yzm.getImage(); HttpServletResponse response= ServletActionContext.getResponse(); Yanzhengma.output(image, response.getOutputStream()); }
-
OGNL–jstl+el:iterator相当于(foreach),if(if)
-
引入标签库:<%@taglib uri="/struts-tags" prefix=“s” %>
-
循环:value为ActionContext.getContext().put(“list”, list);的键值;property标签中value是对象的属性
<s:iterator value="list" var="paste"> <h1>id:<s:property value="id"/></h1> <h1>name:<s:property value="name"/></h1> </s:iterator>
-
if…else语句:
<s:iterator value="list" var="paste"> <s:if test="id%3==0"> <h1>id:<s:property value="id"/></h1>
</s:if>
<s:else>id:9
</s:else>
name:<s:property value=“name”/>
</s:iterator>
-
property:如果访问的是一个类的属性 value="#user.username"
-
eg:user是传递过来的键值队的键
<s:property value="#user.username">
-
拦截器:
-
创建拦截器:
-
第一种:继承MethodFilterInterceptor,实现doIntercept方法(推荐)
public class MyIntercept extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation invocation) throws Exception { //如果用户没有登录就跳转到登录界面 return invocation.invoke();//放行 } }
-
第二种:实现Interceptor接口,重写方法:(可以做一些初始化跟结束时需要做的处理)
public class MyIntercept2 implements Interceptor { @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation invocation) throws Exception { return invocation.invoke();//放行 } }
-
-
配置拦截器(只能控制访问Action):在package标签下
<interceptors> <!-- 注册拦截器 --> <interceptor name="MyIntercept" class="com.rabbit.web.intercept.MyIntercept"></interceptor> <!-- 注册拦截器栈 --> <interceptor-stack name="MyStack"> <!-- 引入自己创建的拦截器 --> <interceptor-ref name="MyIntercept"></interceptor-ref> <!-- 引入struts写好的拦截器(20个) --> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 指定包中的默认拦截器栈,不指定就是默认的struts的20个 现在指定为我们新注册的拦截器,默认的2个加上我们自己创建的1个,构成一个新拦截器栈。将其设置为默认--> <default-interceptor-ref name="MyStack"></default-interceptor-ref>
-
配置不拦截的方法:
<!-- 引入自己创建的拦截器 --> <interceptor-ref name="MyIntercept"> <!-- 配置不拦截的方法():execute() --> <param name="excludeMethods">execute</param> </interceptor-ref>
-