一、struts2入门
举个栗子:hello(步骤)
1.apache官网download下载struts2的包:all.zip 、 lib.zip 、 docs.zip
https://struts.apache.org/download.cgi#struts2522
2.解压lib.zip,里面的jar文件复制到web项目中的WEB-INF/lib路径下,根据需要添加其他jar包。(我下载的2.5.22版本,lib.zip里面8个jar包,黑马中列表13个jar包)
3.若jar包未被开发工具自动添加到classpath中,手动选择所有jar右击Build Path—>Add to BuildPath。
4.配置web.xml:filter标签配置struts2核心过滤器,filter-mapping标签配置该过滤器的映射。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置struts2核心控制器-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
5.定义处理用户请求的Action类:src目录下action包,继承ActionSupport类,定义execute()方法,返回类型String,execute()方法中的返回值对应struts.xml文件中 result 标签中name的属性值。
package action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWordAction extends ActionSupport {
public String excute() throws Exception{
return SUCCESS;
}
}
6.编写struts.xml:src目录下,Action必须放在指定的包空间下,定义package name;定义action name,class对应action类,action的子标签 result 定义处理结果和试图资源之间的映射关系。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!--struts2配置文件的根元素-->
<struts>
<!--struts2的Action必须放在置顶的包空间下定义-->
<package name="hello" namespace="/" extends="struts-default">
<!--定义action,该action的类对应src下action包的对应action-->
<action name="helloword" class="action.HelloWordAction">
<!--定义处理结果和试图资源之间的映射关系-->
<result name="success">/hello_success.jsp</result>
</action>
</package>
</struts>
7.创建jsp视图文件。
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>hello</title>
</head>
<body>
<center><h2>
<a href="${pageContext.request.contextPath}/helloword.action">hello</a><br>
</h2></center>
</body>
</html>
跳转页面:hello_success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>success</title>
</head>
<body>
<center>
<h2>欢迎学习struts2!</h2>
</center>
</body>
</html>
流程:
二、struts2的核心配置
1、struts.xml文件配置
1.1、struts.xml文件
配置action和请求处理的对应关系,以及逻辑视图和物理视图资源对的对应关系
文件中 < struts > 是根元素,所有其他的元素都放其中,< constant >用于进行常量配置;< package >包配置,组织Action和拦截器;< include >包含其他配置文件。
1.2、常量配置
有三种方式:
1.2.1:struts.xml文件中< constant >元素配置常量
name指定常量名,value指定常量值
例:<constant name="struts.i18n.encoding" value="UTF-8">
1.2.2:struts.properties文件中配置常量
在WEB-INF/class路径下,采用key-value对(常量-常量值)
例:struts.i18n.encoding=UTF-8
1.2.3:web.xml文件中通过初始化配置常量
< filter >的子元素< init-param >指定
例:
<init-param>
<param-name>struts.i18n.encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
1.3、包配置
package元素常用属性:
属性 | 说明 |
---|---|
name | 必填属性,指定包名(该包被其他包引用的key) , 唯一标识 |
namespace | 可选属性,定义包的命名空间 |
extends | 可选属性,继承其他包(可包含 Action、拦截器定义) |
abstract | 可选属性,定义是否是抽象包(不能包含Action定义) |
extends属性必须是另一个包的name属性(通常是struts-default,这样Action就有默认的拦截器功能);
显式定义抽象包:abstract=“true”
1.4、包含配置
< include >,分而治之,提高可读性。
2、Action的配置
action实现对用户请求的处理,业务逻辑控制器。
2.1、实现action控制类的三种方式:
2.1.1、POJO的实现
全称Plain Ordinary Java Object,简单的Java对象
POJO类中要有一个公共的无参的构造方法和一个execute方法
public String excute() throws Exception{
return SUCCESS;
}
2.1.2、实现Action接口
com.opensymphony.xwork2包中,定义包含的一些结果字符串(例:public static final SUCCESS="success"
)和execute()方法
很少直接实现Action接口
2.1.3、继承ActionSupport类
必须定义变量serialVersionUID(因为实现了Serializable接口)
private static final long serialVersionUID=1L;
2.2、配置Action
属性 | 说明 |
---|---|
name | 必填,标识action,制定了Action所处理请求的url |
class | 可选,指定action对应的实现类 |
method | 可选,指定请求Action时调用的方法 |
class默认值是ActionSupport,默认方法execute,不作任何处理,返回SUCCESS值。method不指定时调用execute。
2.3、使用通配符
<action name="UserAction_*" class="action.UserAction" method="{1}">
<result>/{1}.jsp</result>
</action>
3、Action访问Servlet API
三种方法:
3.1、通过ActionContext访问
例子:登录
struts.xml
<action name="login" class="action.LoginAction">
<result name="success">/login_success.jsp</result>
<result name="error">/login_error.jsp</result>
</action>
HelloAction中声明俩变量,生产setter&getter方法,然后
public String execute() throws Exception{
//获取ActionContext对象
ActionContext context=ActionContext.getContext();
if(username.equals("aa") && password.equals("123")){
context.put("username",username);
context.put("password",password);
return SUCCESS;
}else {
return ERROR;
}
}
写页面:login.jsp以及俩结果页面login_success.jsp、login_error.jsp
运行:
3.2、通过特定接口访问
接口 | 说明 |
---|---|
ServletRequestAware | 可以直接访问HTTPServletRequest实例 |
ServletResponseAware | 可以直接访问HTTPServletResponse实例 |
SessionAware | 可以直接访问HTTPSession实例 |
SevletContextAware | 可以直接访问ServletContext实例 |
3.3、通过ServletActionContext访问
ServletActionContext类包含的几个静态方法
静态方法 | 说明 |
---|---|
static HTTPServletRequest getRequest() | 获取web应用的HTTPServletRequest对象 |
static HTTPServletResponse getResponse() | 获取web应用的HTTPServletResponset对象 |
static ServletContext getServletContext() | 获取web应用的ServletContext对象 |
static PageContext getPagetContext() | 获取web应用的PageContext对象 |
4、Action处理请求参数
在struts中,页面的请求数据和Action有两种基本的对应方式。
字段驱动/属性驱动,模型驱动
4.1、属性驱动
通过字段进行数据传递,两种情况:
与基本数据类型的属性对应;
直接使用域对象
·4.1.1、与基本数据类型的属性对应
Action中定义各种Java基本数据类型的字段,生成setter、getter方法,对应页面上的表单域
·4.1.2、直接使用域对象
用上面的方法,如果传入数据很多,Action属性增多,代码臃肿,不够简洁。
因此,把属性和对应的setter、getter方法提取出来,单独作为一个域对象,进行封装。JavaBean数据传递的载体。
以登录为例:
(1)src下创domain包,建User实体域对象。
User.java
package domain;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
(2)src下action包 ,创UserLoginAction.java
package action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import domain.User;
public class UserLoginAction extends ActionSupport {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() throws Exception {
//获取ActionContext对象
ActionContext context = ActionContext.getContext();
if (user.getUsername().equals("aa") && user.getPassword().equals("123")) {
context.put("username", user.getUsername());
context.put("password", user.getPassword());
return SUCCESS;
} else {
return ERROR;
}
}
}
(3)写jsp页面,userLogin.jsp,以及成功失败页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>userLogin</title>
</head>
<body>
<div align="center">
<form name="form1" action="userlogin.action" method="post">
用户名:<input type="text" name="user.username"/><br>
密 码:<input type="password" name="user.password"/><br>
<input type="submit" value="登录"/>
</form>
</div>
</body>
</html>
4.2、模型驱动
通过实现ModelDriven接口来接收请求参数,Action类必须实现该接口,且要重写getModel()方法,返回的是Action所使用的数据模型对象。
该模式通过JavaBean模型传递数据。采用该模式,javabean封装的属性和表单属性一一对应,Action类通过get*()方法获取模型
userLoginAction.java
public class UserLoginAction extends ActionSupport implements ModelDriven {
private User user =new User();
@Override
public User getModel() {
return user;
}
public String execute(){
return SUCCESS;
}
}
userLogin.jsp做相应改变:
一个action对应一个model,所以不需要添加user前缀,页面上的username对应这个Model的username。
<form name="form1" action="userlogin" method="post">
用户名:<input type="text" name="username"/><br>
密 码:<input type="password" name="password"/><br>
<input type="submit" value="登录"/>
</form>
5、result
< result >元素有两种属性,都不是必选的
属性 | 说明 |
---|---|
name | 指定逻辑视图的名称,默认是success |
type | 指定返回视图资源的类型,默认值dispatcher |
dispatcher转发,redirect重定向。
<action name="userlogin" class="action.UserLoginAction">
<result name="success" type="dispatcher">/login_success.jsp</result>
<result name="error" type="redirect">/login_error.jsp</result>
</action>