Java - 框架之 Struts2

java

一. Package 标签

1. 标签属性:
name        : 包的名称,只有在一个项目中不重名即可。
extends       : 继承哪个包,默认为 struts-default。
namespace  : 名称空间,与<action> 标签中的 name 属性决定访问路径
    - 名称空间写法:
        - 带名称的: namespace="/a"
        - 不带名称: namespace="/"
        - 默认空间:    namespace=""



二. action 相关配置
1. action 标签配置 Action 类
2. action 标签的属性
    - name         : 与 namespace 共同决定访问路径。
    - class        : Action类的全路径。
    - method    : 执行Action中的哪个方法的方法名,默认 execute。
    - converter : 用户设置类型转换器。



三. 分模块开发配置
include : 用于导入其它的 struts.xml 文件
<include file="xxx/struts.xml">



四. Action 三种编写方式:

1. Action 类是一个POJO的类 (简单的类-没有继承,接口...)

public class ActionDemo1{

public String execute(){

System.out.println("Action1");

return null;

}

}



2. 实现一个Action接口

public class ActionDemo2 implements Action{

@Override

public String execute() throws Exception {

System.out.println("Action2");

return null;

}

}


3. Action类 继承 ActionSupport 类 (常用) ******

public class ActionDemo3 extends ActionSupport{

@Override

public String execute() throws Exception {

System.out.println("Action3");

return None;

}

}



五. Action的三种访问方式

1. method 的配置 :

请求路径:

<a href="${ pageContext.request.contextPath }/userFind.action">跳转</a> 



接收配置路径(struts.xml):

<package name="demo3" extends="struts-default" namespace="/">

<action name="userFind" class="com.xx.demo1.UserAction" method="find"></action>

<action name="userUpdate" class="com.xx.demo1.UserAction" method="update"></action>

<action name="userDelete" class="com.xx.demo1.UserAction" method="delete"></action>

<action name="userSave" class="com.xx.demo1.UserAction" method="save"></action>

</package>



类中:

public class UserAction extends ActionSupport{

public String find(){

return None;

}

...

}




2. 通配符(常用) ******

请求路径:

<a href="${ pageContext.request.contextPath }/product_find.action">跳转</a> 

<action name="product_*" class="com.xxx.ProductAction" method="{1}"></action>

public class ProductAction extends ActionSupport{

public String find(){

return None;

}

...

}


3. 动态方法访问

<a href="${ pageContext.request.contextPath }/customer!find"></a>



# 开启动态方法访问

<constant name="struts.endable.DynamicMethodInvocation" value="true" />

<action name="customer" class="com.xxx.CustomerAction"></action>


类中:

public class CustomerAction extends ActionSupport{

public String find(){

return None;

}

...

}





注意: Servlet 是单例的,Action 是多例的 (不会出现线程安全问题)

六. 访问Servlet API 的三种方式 :

1. 完全解耦和的方式
    
注意:这种方式只能获取代表 request, session, application 的数据的 Map 集合, 不能操作这些对象本身的方法

# 编写 jsp

<form action="${ pageContext.request.contextPath }/requestDemo1.action"  method="post">

姓名:<input type="text" name="name">

密码:<input type="password" name="pwd">

<input type="submit" value="go">

</form>


# 编写Action

public class RequestDemo1 extends ActionSupport{

@Override

public String execute() throws Exception{

// 1. 接收参数

ActionContext context = ActionContext.getContext();

Map<String, Object> map = context.getParamters();

for(String key : map.KeySet()){

String[] values = (String[]) map.get(key);

}

// 2. 向域对象保存数据

context.put("k1","v1"); // 相当于 request.setAttribute();

context.getSession().put("k2","v2"); // 相当于 session.setAttribute();

context.getApplication().put("k3","v3"); // 相当于 application.setAttribute();

return SUCCESS;

}

}



2. 原生的方式访问

注意:可以操作域对象的数据,同时也可以获取对象的方法

# 编写 Action

public class RequestDemo1 extends ActionSupport{

@Override

public String execute() throws Exception{

// 1. 接收参数

ActionContext context = ServletActionContext.getRequest();

Map<String, String[]> map = context.getParamterMap();

for(String key : map.KeySet()){

String[] values = map.get(key);

}

// 2. 向域对象保存数据

// 向 request 中保存数据

request.setAttribute("k1","v1");

// 向 session 中保存数据

request.getSession().setAttribute("k2","v2");

// 向 application 中保存数据

ServletActionContext.getServletContext().setAttribute("k3","v3");

return SUCCESS;

}

}





3. 接口注入方式

public class RequestDemo3 extends ActionSupport implements ServletRequestAware, ServletContextAware{

private HttpServletRequest request;

private ServletContext context;

@Override

public String execute() throws Exception{

// 1. 接受参数

Map<String, String[] map = request.getParamterMap();

Map<String, String[]> map = context.getParamterMap();

for(String key : map.KeySet()){

String[] values = map.get(key);

}

// 2. 向域对象保存数据

// 向 request 中保存数据

request.setAttribute("k1","v1");

// 向 session 中保存数据

request.getSession().setAttribute("k2","v2");

// 向 application 中保存数据

context.setAttribute("k3","v3");

return super.execute();

}

@Override

public void setServletRequest(HttpServletRequest request){

this.request = request;

}

@Override

public void setServletContext(ServletContext context){

this.context = context;

}

}



七. 页面显示配置

1. 全局/局部 结果页面
    - 全局指的是包中一次配置,在这个包中所有 action 返回了这个值,就可以跳转这个页面

<global-results>

<result name="success">/demo1/demo1.jsp</result>

</global-results>

<action name="requestDemo1" class="com.xx">

// 局部

<result name="success">/demo1/demo1.jsp</result>

</action>

// 全局

<action name="requestDemo2" class="com.xx"></action>

<action name="requestDemo3" class="com.xx"></action>


2. result 标签的配置
    - result 标签用于配置页面的跳转,在 result 标签上有两个属性:

name : 逻辑视图的名称,默认值 success。
type : 页面跳转的类型。
    - dispatcher : 默认类型,请求转发 (Action 转发 JSP)
    - redirect   : 重定向。 (Action 重定向 JSP)
    - chain      : 转发。 (Action 转发 Action)
    - redirectAction : 重定向。 (Action 重定向 Action)
    - stream      : Struts2 中提供文件下载的功能。



八. Struts2 的数据封装

1. 属性驱动:提供属性的 set 方法

# 编写 Action

public class UserAction1 extends ActionSupport {

private String name;

private String pwd;

// 属性的 set 方法:

public void setName(String name){ this.name=name; }

public void setPwd(String pwd){ this.pwd=pwd; }

@Override

public String execute() thows Exception {

// 接收数据

System.out.println(name);

System.out.println(pwd);

// 封装数据

User user = new User();

user.setName(user);

user.setPwd(pwd);

return NONE;

}

}



2. 属性驱动:页面中提供表达式
# 页面

<form>

// Action 对象的属性名(user.跟set方法名一直)

<input type="text" name="user.name">

</form>



# 编写 Action

public class UserAction1 extends ActionSupport {

// 提供一个 User 对象

private User user;

// 提供 user 的 get和set 方法: get必给

public User getUser(){

return user;

}

public void setUser(User user){

this.user = user;

}

@Override

public String execute() throws Execption {

System.out.println(user);

return NONE;

}

}




3. 模型驱动 (常用)

# 编写 Action

// 手动提供实例对象

private User user = new User();

@Override

public User getModel() {

return user;

}

@Override

public String execute() throws Exception {

System.out.println(user);

return NONE;

}



九. Struts 的复杂类型数据封装

1. 封装数据到 List 集合中

# 编写 JSP

<input type="text" name="products[0].name">

<input type="text" name="products[0].price">

<input type="text" name="products[1].name">

<input type="text" name="products[2].price">



# 编写 Action

public class ProductAction1 extends ActionSupport{

private List<product> products;

// 提供set 和 get 方法

public List<Product> setProducts(){

this.products = products;

}

public List<Product> getProducts(){

return products;

}

@Override

public String execute() throws Exception{

for(Product product : products) {

System.out.rpint(product);

}

return NONE;

}

}



2. 封装数据到 Map 集合中

# 编写 JSP

<input type="text" name="map["a"].name">

<input type="text" name="map["a"].price">

<input type="text" name="map["b"].name">

<input type="text" name="map["b"].price">


# 编写 Action

public class ProductAction1 extends ActionSupport{

private Map<String, Product> map;

// 提供set 和 get 方法

public Map<String, Product> getMap(){

return map;

}

public void setMap<Map<String, Product> map){

this.map = map;

}

@Override

public String execute() throws Exception{

for(Product key : map.KeySet()) {

Product product = map.get(key);

System.out.rpint(key+ "" +product);

}

return NONE;

}

}



十. OGNL

0. 值栈(ValueStack)
类似于一个数据中转站( Struts2 框架中的数据都存储在了 ValueStack 中 )
    - ValueStack 接口,实现类 OgnlValueStack 对象。
    - ValueStack 贯穿整个 Action 的生命周期 (Action一旦创建,框架就会创建一个 ValueStack 对象)。

// 值栈内部结构
Root    : CompoundRoot, 就是一个 ArrayList;
Context : OgnlContext, 就是一个Map。


1. 调用对象的方法
<s:property value="'字符串'.length()" />


2. 访问对象的静态方法

// 静态方法访问在 Struts2 中默认是关闭的

<s:property value="@java.lang.Math@random()" />

// 开启静态方法访问权限

<constant name="struts.ongl.allowStaticMethodAccess" value="true" />



3. 操作值栈 - 存入数据

// 方式一:使用 Action 本身在值栈中的特性

public class ValueStackDemo3 extends ActionSupport{

private User user;

// 需要提供 get 方法

public User getUser(){

return user;

}

@Override

public String execute() throws Exception{

// ValueStack 中存值

user = new User("a","2");

return SUCCESS;

}

}

// 方式二:使用值栈中的方法实现

public class ValueStackDemo4 extends ActionSupport{

@Override

public String execute() throws Exception{

ValueStack valueStack = ActionContext.getContext().getValueStack();

// 此时 User在栈顶的位置

User user = new User("b","3");

ValueStack.push(user);

//创建一个Map集合,将Map加入栈中

ValueStack.set("name","zs");

return super.execute();

}

}



3. 操作值栈 - 获取数据

public class ValueStackDemo5 extends ActionSupport{

@Override

public String execute() throws Exception{

// 向值栈中保存一个对象

User user = new User("a","1");

ActionContext.getContext().getValueStack().push(user);

// 向值栈中保存一个集合

List<User> list = new ArrayList<User>();

list.add(new User("b","1"));

list.add(new User("c","1"));

list.add(new User("d","1"));

ActionContext.getContext().getValueStack().set("list", list);

// 向 context 中存入数据

ServletActionContext.getRequest().setAttribute("name","q1");

ServletActionContext.getRequest().getSession.setAttribute("name","q2");

ServletActionContext.getServletContext().setAttribute("name","q3");

return super.execute();

}

}


# XML 文件

# 获取一个对象的数据

<s:property value="username" />

<s:property value="password" />

# 获取集合中的数据

<s:property value="list[0].username" />

<s:property value="list[0].password" />

<s:property value="list[1].username" />

<s:property value="list[1].password" />

# 获取context中的数据

<s:property value="#request.name" />

<s:property value="#session.name" />

<s:property value="#application.name" />

<s:property value="#attr.name" />

// 接收参数: xxx?id=1

<s:property value="#paramters.id" />




十一. OGNL 符号

0. 获取 context 的数据:

<%

request.setAttribute("name","q1");

%>



1. 使用 # 构建map 集合

<s:iterator var="entry" value="#{ 'a':'1', 'b':'2', 'c':'3' }"

<s:property value="key" /> - <s:property value="value" />

<s:property value="#entry.key"> - <s:property value="#entry.value" />

</s:iterator>

<s:radio list="#{'1':'男', '2':'女'}" name="sex" label="性别" />



2. 使用 %

<%

request.setAttribute("name","q1");

%>

// 强制解析为 OGNL

<s:textfield name="name" value="%{#request.name}" />

// 强制不解析 OGNL

<s:property value="%{'#request.name'}" />


3. 使用 $
// 属性文件
# 国际化

// XML文件

<param name="COntent-Disposition">filename=${ 文件名 }</param>





十二. Struts2 拦截器

1. 编写拦截器

public class InterceptorDemo1 extends AbstractInterceptor{

@Override

public String intercept(ActionInvocation invocation) throws Exception{

System.out.prinln("拦截器");

return invocation.invoke();

}

}



2. 拦截器配置

方式一:

// 方式一: 定义拦截器配置

<package name="demo1" extends"struts-default" namespace="/">

// 定义拦截器

<interceptors>

<interceptor name="interceptorDemo1" class="com.xx.InterceptorDemo1" />

<interceptor name="interceptorDemo2" class="com.xx.InterceptorDemo2" />

</interceptors>

<action name="actionDemo1" class="com.xxx.ActionDemo1">

<result>/demo1/demo1.jsp</result>

// 引入拦截器 (注意:一旦引入自定义拦截器,默认拦截器就不会执行了)

<interceptor-ref name="defaultStack" /> // 引入默认拦截器

<interceptor-ref name="interceptorDemo1" /> // 自定义拦截器

<interceptor-ref name="interceptorDemo2" /> // 自定义拦截器

</action>

</package>


方式二:

// 方式二: 定义拦截器栈

<package name="demo1" extends"struts-default" namespace="/">

<interceptors>

<interceptor name="interceptorDemo1" class="com.xx.InterceptorDemo1" />

<interceptor name="interceptorDemo2" class="com.xx.InterceptorDemo2" />

// 定义拦截器栈

<interceptor-stack name="myStack">

<interceptor-ref name="defaultStack" /> // 引入默认拦截器

<interceptor-ref name="interceptorDemo1" /> // 自定义拦截器

<interceptor-ref name="interceptorsDemo2" /> // 自定义拦截器

</interceptor-stack>

</interceptors>

<action name="actionDemo1" class="com.xxx.ActionDemo1">

<result>/demo1/demo1.jsp</result>

// 引入拦截器栈

<interceptor-ref name="myStack" />

</action>

</package>



十三. 通用标签库

1. 导入

<$@ taglib uri="/struts-tags" prefix="s" %>


2. 判断标签

<s:set var="i" value="1" scope="request" />

<s:if test="#request.i>3">

大于3

</s:if>

<s:elseif test="#request.i<3">

小于3

</s:if>

<s:else>

等于3

</s:if>



3. 循环标签

// 遍历 list

<s:iterator var="i" value="{'a','b','c'}">

<s:property value="#i">

</s:iterator>s

// 遍历 map

<s:iterator var="entry" value="#{'aaa':'111', 'bbb':'222', 'ccc':'333'}">

<s:property value="#entry.key" /> -- <:property value="#entry.value" />

</s:iterator>

// 遍历 数字

<s:iterator var="i" begin="1" end="10" step="1">

<s:property value="#i" />

</s:iterator>



十三. UI标签库
文档走起..


十四. Struts2 执行流程

请求-> 核心过滤器-> 创建 ActionProxy 方法, 在这个内部-> ActionInvocation.invoke() 在这个方法中递归执行一组拦截器
-> Action -> Result(最终返回一个字符) -> 拦截器之后的代码..

以上是 Java - 框架之 Struts2 的全部内容, 来源链接: utcz.com/z/392442.html

回到顶部