0%

Struts2

Struts2


struts2介绍

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

Idea使用struts2

  1. 点击File->new->Project...,选择Java Enterprise中的Struts2,libraries中选择Use library

    点击create...,选择下载好的struts2的lib中的jar包

  2. 点击next->Finish然后项目建立完成

  3. 点击File->Project structure...,选择Problems,会发现有一个问题,点击Fix,选择Add.....,然后ok就行了

  4. 查看web.xml文件,如果有红色报错,只需要将org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter改成org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter即可

  5. 如果有报错Artifact untitled:war exploded: Error during artifact deployment.

    则需要检查

    1. Project structure中的Problems是否仍然存在,若存在则继续Fix
    2. Project structure中的Artifacts中Web-INF中是否有导入的struts2lib,
    3. 确保只导入过一次Struts2的lib文件,在Exernal Libraries中导入后,不要在tomcat文件夹中的lib中导入struts2的jar包

    全部修改完成后,点击运行就可以成功运行了。

使用struts2完成一个简单的登录

以一个登录案例为例:

Service、dao、pojo文件都和用Servlet时基本一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- login.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<!-- 注意修改action -->
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="uname"><br>
密码: <input type="password" name="pwd"><br>
<input type="submit">
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* LoginAction.java
* 作用和Servlet类似
*/
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zephon.pojo.User;

public class LoginAction extends ActionSupport implements ModelDriven {

private User user = new User();

@Override
public String execute() throws Exception {
boolean success = new UserService().checkLogin();
System.err.println(user.getUname());

if(success){
return "success";
}
return "error";
}

// 实现ModelDriven接口,实现getModel方法,返回一个对象就是我们封装数据的对象(先要将对象封装)
@Override
public User getModel() {
return user;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://img/truts.apache.org/dtds/img/truts-2.5.dtd">

<!-- struts.xml -->
<struts>
<!-- name:配置包名,namespace:给action的访问路径定义一个命名空间 -->
<package name="MyPackage" namespace="/" extends="struts-default">
<!-- action:配置action类
name:决定action访问的资源名称相当于servlet:url-pattern
class:action的完整类名
method:指定调用action中的哪个方法去处理请求 -->
<action name="LoginAction" class="com.zephon.action.LoginAction" method="execute">
<!-- 默认为请求转发,可修改为重定向 -->
<result name="success" type="redirect">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</img/truts>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- web.xml idea一般会自动配置好 -->
<?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">

<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>

<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>

动态设置方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://img/truts.apache.org/dtds/img/truts-2.5.dtd">

<struts>

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

<!-- name:配置包名 -->
<package name="MyPackage0" namespace="/" extends="struts-default">

<global-allowed-methods>login,register</global-allowed-methods>

<action name="LoginAction_*" class="com.zephon.action.LoginAction" method="{1}">
<!-- 默认为请求转发 -->
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</img/truts>

log4j警告问题解决

导入log4j-core-*.jar包,然后在src中添加log4j2.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n" />
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>

参数传递

接收参数

  1. (常用)
1
2
3
4
5
6
7
8
9
10
11
12
public class LoginAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
@Override
public String execute() throws Exception {
System.err.println(user.getUname());
return "success";
}
@Override
public User getModel() {
return user;
}
}
  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class LoginAction extends ActionSupport {

    private String uname;
    private String pwd;

    @Override
    public String execute() throws Exception {
    boolean success = true;
    System.out.println(uname+"--"+pwd);
    if(success){
    return "success";
    }
    return "error";
    }

    public String getUname() {
    return uname;
    }

    public void setUname(String uname) {
    this.uname = uname;
    }

    public String getPwd() {
    return pwd;
    }

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

1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="user.uname"><br>
密码: <input type="password" name="user.pwd"><br>
<input type="submit">
</form>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class LoginAction extends ActionSupport {
public User user;
@Override
public String execute() throws Exception {
boolean success = true;
System.out.println(user.getUname()+"--"+user.getPwd());
if(success){
return "success";
}
return "error";
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}
}

传递参数(给jsp或action)

使用ActionContext,map类型,包括request,response,servletContext,request域,session域,application域,attr域,param域,valueStack值栈

生命周期:每次请求都会创建一个对应的actioncontext对象,请求结束去销毁actionContext对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//使用ActionContext
//request中的setAttr
ActionContext.getContext().put("uname","123");
ActionContext.getContext().put("pwd","123");
//获得session
Map<String,Object> session = ActionContext.getContext().getSession();
session.put("session","session域");
//获得application
Map<String,Object> application = ActionContext.getContext().getApplication();
application.put("application","application域");
//获得原生的request
HttpServletRequest request = ServletActionContext.getRequest();
//获得原生的response
HttpServletResponse response = ServletActionContext.getResponse();

OGNL

可看作是EL+JSTL表达式

循环遍历:

1
2
3
<s:iterator value="list" var="l">
<s:property value="name"/><!-- 属性 -->
</img/:iterator>

条件语句:

1
2
3
4
5
6
<s:if test="num%2==0">
偶数
</img/:if>
<s:else>
奇数
</img/:else>

拦截器

拦截器只能控制访问Action,不能控制访问jsp页面

创建拦截器

1
2
3
4
5
6
7
8
9
10
11
//第一种创建拦截器的方法(推荐) 继承类MethodFilterInterceptor
public class MyIntercept extends MethodFilterInterceptor {

@Override
protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
//如果没有登录就跳转到登录页面
return "Login";
// 放行
// return actionInvocation.invoke();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//第二种(实现Interceptor接口)
public class MyIntercept1 implements Interceptor {

@Override
public void destroy() {

}

@Override
public void init() {

}

@Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
//放行
return actionInvocation.invoke();
}
}

配置拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<package name="MyPackage" namespace="/" extends="struts-default">
<interceptors>
<!-- 注册拦截器 -->
<interceptor name="MyIntercept" class="com.zephon.intercept.MyIntercept"></interceptor>
<!-- 注册拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 引入自己创建的拦截器 -->
<interceptor-ref name="MyIntercept">
<!-- 配置不经过拦截器的 -->
<param name="excludeMethods">execute</param>
</interceptor-ref>
<!-- 引入struts写好的拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定包中的默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
</package>