文章目录
1 前言知识
struts2其实就是一个MVC框架,把不同的功能代码分离。其中M(Model)用的是JavaBean,可以高效地匹配键值对。V(View)用的是JSP,C(Controller)使用的是继承ActionSupport类,其中最主要的函数就是execute函数,后面会讲到。最后一点就是xml的配置文件,这个文件可以用于把view中的请求发送到Controller里面,在controller里面使用Model方法,处理数据,然后转发给View展示页面,由此来实现MVC模式。
- 典型的MVC框架有struts1、webwork、jsf、struts2、springMVC、nutz、jersey等等。
- struts2是由Struts1和webwork整合而来,是Apache下的一个项目。
- 目录结构:
apps:项目案例
docs:学习文档
lib:所需的jar包
src:Struts2的源码 - MVC框架完成的事情:
a. 用户请求(url)映射到一个java类;
b. 获取用户提交的数据;
c. 将数据封装到前台显示(request)——渲染数据;
d. 控制显示视图,视图跳转。
Servlet:处理用户提交的数据、调用业务方法 处理业务结果、控制视图显示
Model 1------Model2(mvc框架)
当一个方法中的部分代码在不断重复——抽出来作为一个单独的方法;
当有很多个同类型的方法时——抽出来作为一个类;
当有很多类在重复处理一类事情时——抽出来作为一个jar包——框架(不做重复的劳动)
学习框架主要就是学习框架的规则,在框架的规则下去做事。
使用框架的原因:提高开发效率;
2 搭建项目Struts2-demo步骤
eclipse搭建项目:
- 新建Dynamic Web Project项目
- 导入所需的jar包:
commons-fileupload-x.y.z.jar
commons-io-x.y.z.jar
commons-lang-x.y.jar
commons-logging-x.y.z.jar
commons-logging-api-x.y.jar
freemarker-x.y.z.jar
javassist-x.y.z.GA
ognl-x.y.z.jar
struts2-core-x.y.z.jar
xwork-core.x.y.z.jar - 配置Struts2核心控制器,web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>StrutsLogin</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
- 在src下添加Struts2的配置文件,编辑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="default" namespace="/" extends="struts-default">
<action name="login" class="com.LoginAction">
<result name="success">/success.jsp</result>
<result name="failed">/login.jsp</result>
</action>
</package>
</struts>
注:详情见第五大点:常量配置文件详解
- 编辑login.jsp页面
<body>
<form action="login.action" method="post">
用户名:<input type="text" name="name" /><br>
密码:<input type="password" name="pwd" /><br>
<input type="submit" value="登录" />
</form>
</body>
注:action的提交地址: .action是默认的扩展名;action的扩展名和web.xml中配置的struts2的核心过滤器相匹配;也就是如果表单中提交的地址以.action结尾,那么在配置filter的<url-pattern>*.action</url-pattern>
- 编写action类——LoginAction
(注:servlet中默认执行service方法,Struts2中默认执行execute方法)
public class LoginAction {
private String name;
private String pwd;
//处理方法
public String execute() {
if("lxy".equals(name) && "1111".equals(pwd)) {
return "success";
} else {
return "failed";
}
}
//...getter,setter方法
}
注:LoginAction中的属性名和表单中表单元素的名称要一致。要为属性提供getter/setter方法,struts2自动将用户提交的表单数据设置到LoginAction的对应属性上。并且在jsp中可以直接获取,不用手动向request设置。
- 配置action类——在struts.xml文件中配置HelloAction(Struts2基于包管理),图见步骤4。
idea创建项目
File-new-Project:在创建Project的时候选上Struts2
3 流程图
这将产生一个流程图:
当用户提交一个请求,服务器接收,并且交给struts2的核心过滤器来进行处理,struts2的过滤器调用struts2的一系列处理器来进行处理(如:解析struts2.xml配置文件,和用户提交的请求对比,如果找不到返回404,如果找到进行下一步处理。)直到调用对应的Action类中的execute方法执行,执行完后再进行一系列处理到核心过滤器。由核心过滤器返回给服务器,服务器对浏览器进行相应的响应。
详细流程:
4 struts2线程安全
- 线程安全:在一个进程中有多个线程并发执行,每个线程执行过程中,变量值是相同的,执行结果也是相同的。
- struts2线程安全吗?
每次请求都会重新创建新的action对象,所以线程安全。
由于action对象是struts2反射生成的,所以要求action类要有一个公共的无参构造方法。
servlet单例
5 常量配置文件详解
1 常量配置方式一
- 乱码处理
<constant name="struts.i18n.encoding" value="UTF-8" />
- 自定义扩展名
<constant name="struts.action.extension" value="action,,lxy"></constant>
- 配置文件修改后自动装载–推荐在开发中使用
<constant name="struts.configuration.xml.reload" value="true" />
- 友好的提示信息
<constant name="struts.devMode" value="true" />
2 常量配置方式二
- 在src下添加struts.properties配置文件
- #set extension
struts.action.extension=action,lxy
3 团队协作开发配置
通过include添加不同人员的配置文件
<include file="config/struts/user.xml" />
4 配置文件加载顺序
struts-default.xml----->struts-plugin.xml----->struts.xml
5 package的配置
//包的名称,可以配置多个包;namespace命名空间:不同模块可以指定不同的空间,
// extends值是直接或者间接继承struts-default
<package name="user" namespace="/" extends="struts-default">
<action name="test" class="control.TestAction" method="test">
<result name
</action>
</package>
6 action的配置
/** name是url请求名,不需要加后缀(.action),class是处理url请求对应的Java类,
class要求包名+类名,并且该类是由公共的无参构造方法的。method配置处理请求类的处理的方法,
默认为execute; 方法要满足是公共的,返回值类型是String,无参.
method和name无关,名称可以不一样。
**/
<action name="login" class="com.LoginAction">
<result>/success.jsp</result>
<result name="failed">/login.jsp</result>
</action>
<action name="logout" class="com.LoginAction" method="logout">
<result>/success.jsp</result>
</action>
7 result的配置
result指的是结果集
name:匹配请求处理方法的返回值,默认是success
type:结果处理类型,默认是dispatcher转发
type类型见struts-default.xml
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
chain:指action链,链接下一个action;执行actionA以后直接执行actionB后执行actionC,
用的较少地址栏是执行的第一个action
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
***dispatcher:转发,和servlet一致。如果request中有数据要到视图显示,那么使用dispatcher
***redirect:重定向,如果重定向到jsp页面,可以直接重定向,如果是重定向到另一个action,需注意
是否配置了action的后缀名,如果要求有后缀名,那么重定向的action一定要加上后缀名
***redirectAction:重定向另外一个action,不用加action后缀名,会将前一个action的后缀名自动加上
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
***stream:以流的形式显示————文件下载
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
<result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>
8 全局配置
- 配置全局结果集:
<global-results>
<result name="login">/login.jsp</result>
</global-results>
- 在action的配置中,如果不去配置class属性,将会由默认的action来执行,默认的action是ActionSuppot类。
配置默认执行的class:
<default-class-ref class="com.AddAction" />
- 配置默认的action:(当所请求的action不存在时,那么执行默认的action)
<default-action-ref name="default" />
9 通配符的配置
使用通配符来配置action,可以减少action的配置,*
表示匹配所有,占位符{1}
表示第一个*
所代表的内容:
<action name="user*" class="com.AddAction" method="{1}">
<result>/index.jsp</result>
</action>
- 减少action的配置还可以使用DMI(动态方法调用),不推荐,存在安全隐患。
6 action的三种实现方式
6.1 定义一个普通的pojo类
好处:自定义的一个普通的java类,不具有侵入性(继承或者实现框架的类或接口)
public class PojoAction {
public String execute() {
System.out.println("pojo action");
return "success";
}
}
6.2 实现Action接口
步骤:
- Action类实现Action接口,重写execute()方法,返回时使用Action接口中的常量;
- 在Action中声明成员变量,成员变量名与表单项name属性一致;
- 封装。
好处:使得我们编写的代码更加规范
public class InterfaceAction implements Action{
@Override
public String execute() throws Exception {
System.out.println("interface action");
return SUCCESS;
}
}
Action接口代码:
public interface Action{
// 定义Action接口里包含的一些结果字符串
public static final String ERROR="error";
public static final String INPUT="input";
public static final String LOGIN="login";
public static final String NONE="none";
public static final String SUCCESS="success";
// 定义处理用户请求的execute方法
public String execute() throws Exception;
}
6.3 继承ActionSupport类(推荐)
ActionSupport类是Action接口的实现类。该类提供了许多默认的方法,这些默认方法包括获得国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等。
如果配置Action没的指定的Action类,系统自动使用ActionSupport类作为Action处理类。
步骤:
- 继承ActionSupport,重写execute()方法。不继承也可以,直接写execute()方法;
- 在Action中声明成员变量,成员变量名与表单项name属性一致;
- 封装。
好处:可以继承一些ActionSupport实现功能,如:验证;官方推荐使用
public class ExtendsAction extends ActionSupport{
// 可以不用重写这个方法
@Override
public String execute() throws Exception {
System.out.println("extends action");
return SUCCESS;
}
}
7 以对象的方式处理表单数据
1 属性驱动
属性驱动有三种:普通POJO类、实现Action接口、继承ActionSupport(推荐)。
- jsp页面(关注点在标签里的name)
<body>
<form action="register.action" method="post">
用户名:<input type="text" name="user.name" /><br>
密码:<input type="password" name="user.pwd"><br>
年龄:<input type="text" name="user.age"><br>
邮箱:<input type="text" name="user.email"><br>
<input type="submit" value="提交" />
</form>
</body>
- action代码
public class UserAction {
private User user; // 命名时:mUser不正确,getter/setter方法名的问题
// 注册
public String register() {
System.out.println(user);
return Action.SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
- User类
public class User {
private String name;
private String pwd;
private int age;
private String email;
// 。。。getter/setter方法
@Override
public String toString() {
return "User [name=" + name + ", pwd=" + pwd + ", age=" + age + ", email=" + email + "]";
}
}
- struts.xml文件
<struts>
<package name="user" extends="struts-default">
<action name="register" class="lxy.action.UserAction" method="register">
<result name="success">/show.jsp</result>
</action>
</package>
</struts>
2 模型驱动(ModeDriven)
就是使用单独的JavaBean实例来贯穿整个MVC流程,JavaBean实例封装请求参数和处理结果。
模型驱动有一种:ModelDriven。
模型驱动封装:ModelDriven(推荐)
模型驱动:就是使用单独的JavaBean实例来贯穿整个MVC流程,JavaBean实例封装请求参数和处理结果。
步骤:
- Action类实现ModelDriven接口;
- 实现接口的getModel()方法,并把创建对象返回;
- 在Action中创建实体类对象;
- execute()一样法中使用实体类对象名即可。
jsp代码
<body>
<form action="regDriven.action" method="post">
用户名:<input type="text" name="name" /><br>
密码:<input type="password" name="pwd"><br>
年龄:<input type="text" name="age"><br>
邮箱:<input type="text" name="email"><br>
<input type="submit" value="提交" />
</form>
</body>
- action代码(重点:实现接口;new对象;getModel方法)
public class UserDrivenAction implements ModelDriven<User>{
private User user = new User();
// 注册
public String register() {
System.out.println(user);
return Action.SUCCESS;
}
@Override
public User getModel() {
return user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
- 实体类方法(和jsp的属性名称对应)
如上属性驱动 - struts.xml配置
如上属性驱动
模型驱动相比属性驱动,代码量少一点。建议在实体类属性比较多时,采用模型驱动进行开发。
8 获取servlet的API
- struts2有2种方式去获取servlet API;一种解耦,一种耦合。
解耦使得使用struts2来进行测试的时候,不需要启动服务器,在一定程度上提高开发效率。
action —> sevice —> dao - 使用解耦的方式来获取servlet API;通过ActionContext对象获取。
ActionContext.getContext().getSession().put(“user”, name);
//处理方法
public String execute() {
if("lxy".equals(name) && "1111".equals(pwd)) {
// 获取session
ActionContext.getContext().getSession().put("user", name);
// 获取request-----HttpServletRequest对象的attributes
Map<String,Object> request = (Map)ActionContext.getContext().get("request");
// 获取application
Map<String,Object> application = ActionContext.getContext().getApplication();
// 获取parameters
Map<String,Object> parameters = ActionContext.getContext().getParameters();
// 相当于request.getParameter("name");
System.out.println("name===" + ((String[])parameters.get("name"))[0]);
return "success";
}else {
return "login";
}
}
- 通过ActionContext直接获取HttpServletRequest
HttpServletRequest requests = (HttpServletRequest) ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
StrutsStatics也可以获取response - 通过耦合的方法获取HttpServletRequest,实现ServletRequestAware接口
实现接口; HttpServletRequest request; request.getSession().setAttribute(“user”,name);
public void setServletRequest(HttpServletRequest request) {
this.request = request;
} - 通过获取ServletActionContext获取HttpServletRequest
HttpServletRequest request = ServletActionContext.getRequest();
建议第一种和第四种
9 案例——maven,struts2小案例(登录注册)
win10,Idea,Tomcat 8.5,mysql 实现
https://blog.csdn.net/weixin_45044097/article/details/102556304