struts2的hello world
1、导包(自行导包)
2、配置web.xml文件
struts2基于拦截器,配置的第一步是在WEB-INF/web.xml中配置struts2拦截器。
<?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>struts2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置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>
3、配置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: 包,struts2 使用 package 来组织模块.
name属性:必须,用于其它的包引用当前包.
extends:当前包继承哪个包,即可以继承其中的所有的配置,通常情况下继承 struts-default
struts-default 这个包在 struts-default.xml 文件中定义
namespace:可选, 如果它没有给出,则以 / 为默认值.
若 namespace 有一个非默认值,则要想调用这个包里的Action,
就必须把这个属性所定义的命名空间添加到有关的 URI 字符串里
http://localhost:8080/contextPath/namespace/actionName.action
-->
<package name="default" namespace="/" extends="struts-default">
<!--
action:一个 struts2 的请求就是一个 action
name:对应一个 struts2 的请求的名字(或对一个 servletPath, 但去除 / 和扩展名)
class:当前 action 所属的全类名,默认值为: com.opensymphony.xwork2.ActionSupport
method:当前 action 对应的方法名,默认值为: execute
-->
<action name="hello" class="com.bjlemon.action.HelloAction" method="execute">
<!--
result: 结果,表示 action 方法执行后可能返回的一个结果。
一个 action 节点可能会有多个 result 子节点.
多个 result 子节点使用 name 来区分
name:标识一个 result 和 action 方法的返回值对应,默认值为 success
type: 表示结果的类型. 默认值为 dispatcher(转发到结果.)
-->
<result name="success" type="dispatcher">/hello.jsp</result>
<action name="index">
<result>/index.jsp</result>
</action>
</action>
</package>
<!-- 就是引入其他的struts2配置文件 -->
<!-- <include file=""></include> -->
</struts>
4、写一个HelloAction类
public class HelloAction extends ActionSupport{
public String execute() {
System.out.println("hello world");
return "success";
}
}
5、编写一个hello.jsp页面和index.jsp页面
hello.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>struts2</title>
</head>
<body>
hello world
</body>
</html>
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>struts2</title>
</head>
<body>
hello struts
</body>
</html>
6、测试
配置好后,就可以通过浏览器访问(根路径取决于项目配置)
http://127.0.0.1/strut2/hello.action
如果访问成功,jsp页面也会显示hello struts
http://127.0.0.1/strut2/hello.action
如果访问成功,控制台后打印 hello world,jsp页面也会显示hello world
7、补充(注解配置如下)
// 使用注解前必须导入 struts2-convention-plugin 包
@ParentPackage("struts-default")
public class HelloAction extends ActionSupport{
@Action(value="hello",results= {
@Result(name="success",location="/hello.jsp")
})
public String execute() {
System.out.println("hello world");
return "success";
}
}
struts2常量配置
<!-- 处理乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- 配置访问后缀名 -->
<constant name="struts.action.extension" value="action,,"></constant>
<!-- 是否开启开发模式(热加载) -->
<constant name="struts.devMode" value="false"></constant>
<!-- 调用动态方法 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
动态方法调用
HelloAction
public class HelloAction extends ActionSupport{
public String execute() {
System.out.println("hello world");
return "success";
}
public String execute1() {
System.out.println("hello world1");
return "success";
}
public String execute2() {
System.out.println("hello world2");
return "success";
}
}
<!-- 如果请求的时候找不到Action,就会执行index -->
<default-action-ref name="showStudent"></default-action-ref>
<!-- 动态方法允许调用的方法名 -->
<global-allowed-methods>execute1,execute2,execute3</global-allowed-methods>
<!-- 动态方法调用(第一种感叹号不常用),访问hello!方法名 -->
<action name="hello" class="com.bjlemon.action.HelloAction">
<result name="success">/hello.jsp</result>
</action>
<!-- 动态方法调用(第二种通配符常用),访问hello_方法名 -->
<action name="hello_*" class="com.bjlemon.action.HelloAction" method="{1}">
<result name="success">/hello.jsp</result>
</action>
Action的创建方式
//第一种方式
public class HelloAction{}
//第二种方式
public class Test implements Action{
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
//第三种方式
public class HelloAction extends ActionSupport{}
Action中result处理方式
<?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">
<!-- 第一种:请求转发(type="dispatcher")默认方式 -->
<action name="hello1" class="com.bjlemon.action.Action1" method="hello1">
<result name="success1" type="dispatcher">/hello.jsp</result>
</action>
<!-- 第二种:请求重定向(type="redirect") -->
<action name="hello2" class="com.bjlemon.action.Action1" method="hello1">
<result name="success1" type="redirect">/hello.jsp</result>
</action>
<!-- 第三种:请求转发到Action(type="chain") -->
<action name="hello3" class="com.bjlemon.action.Action1" method="hello1">
<result name="success1" type="chain">
<!-- 跳转的action的名字 -->
<param name="actionName">hello1</param>
<!-- 跳转的action的命名空间 -->
<param name="namespace">/</param>
</result>
</action>
<!-- 第四种:请求重定向到Action(type="redirectAction") -->
<action name="hello4" class="com.bjlemon.action.Action1" method="hello1">
<result name="success1" type="redirectAction">
<!-- 跳转的action的名字 -->
<param name="actionName">hello1</param>
<!-- 跳转的action的命名空间 -->
<param name="namespace">/</param>
</result>
</action>
</package>
</struts>
Action获取servlet api
//获得原生的servlet作用域对象 方式一
public class Action1 extends ActionSupport{
public String hello1() {
HttpServletRequest request=ServletActionContext.getRequest();
request.setAttribute("key", "value");
HttpSession session=request.getSession();
HttpServletResponse response=ServletActionContext.getResponse();
ServletContext servletContext=ServletActionContext.getServletContext();
return "success1";
}
}
//获得原生的servlet作用域对象 方式二
public class Action1 extends ActionSupport implements ServletRequestAware,ServletResponseAware,ServletContextAware{
private HttpServletRequest request;
private HttpServletResponse response;
private ServletContext servletContext;
@Override
public void setServletRequest(HttpServletRequest request) {
this.request=request;
HttpSession session=request.getSession();
}
@Override
public void setServletResponse(HttpServletResponse response) {
this.response=response;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext=servletContext;
}
}
//获得原生的ActionContext作用域对象(常用) 方式一
public class Action1 extends ActionSupport{
public String hello2() {
Map<String, Object> request=(Map<String, Object>)ActionContext.getContext().get("request");
ActionContext context=ActionContext.getContext();
context.put("key", "value");
Map<String, Object> session=ActionContext.getContext().getSession();
session.put("key", "value");
Map<String, Object> application=ActionContext.getContext().getApplication();
return "success1";
}
}
//获得原生的ActionContext作用域对象(常用) 方式二
public class Action1 extends ActionSupport implements RequestAware, SessionAware, ApplicationAware {
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}
}
struts2接收前台传过来的参数的方式
第一种方式:属性加载驱动
index.jsp
<form action="${pageContext.request.contextPath}/hello1" method="post">
<input type="text" name="name">
<input type="text" name="age">
<input type="text" name="date">
<input type="submit" value="提交">
</form>
public class Action1{
private String name;
private Integer age;
private Date date;
//...省略getter/setter方法
public String hello1() {
System.out.println(name+"-"+age+"-"+date);
return "success1";
}
}
第二种方式:对象加载驱动
index.jsp
<form action="${pageContext.request.contextPath}/hello1" method="post">
<input type="text" name="student.name">
<input type="text" name="student.age">
<input type="text" name="student.date">
<input type="submit" value="提交">
</form>
Student.java
public class Student {
private Integer id;
private String name;
private Integer age;
private Date date;
//...省略getter/setter方法
}
public class Action1{
private Student student;
//...省略getter/setter方法
public String hello1() {
System.out.println(student);
return "success1";
}
}
第三种方式:ModelDriven模型驱动
index.jsp
<form action="${pageContext.request.contextPath}/hello1" method="post">
<input type="text" name="name">
<input type="text" name="age">
<input type="text" name="date">
<input type="submit" value="提交">
</form>
public class Student {
private Integer id;
private String name;
private Integer age;
private Date date;
//...省略getter/setter方法
}
public class Action1 implements ModelDriven<Student>{
private Student student=new Student();
public String hello1() {
System.out.println(student);
return "success1";
}
@Override
public Student getModel() {
return student;
}
}
接收list集合
<form action="${pageContext.request.contextPath}/hello1" method="post">
<input type="text" name="list">
<input type="text" name="list">
<input type="text" name="list">
<input type="submit" value="提交">
</form>
public class Action1{
private List<String> list;
//...省略getter/setter方法
public String hello1() {
System.out.println(list);
return "success1";
}
}
接收map集合
<form action="${pageContext.request.contextPath}/hello1" method="post">
<input type="text" name="map['KEY0']">
<input type="text" name="map['KEY1']">
<input type="text" name="map['KEY2']">
<input type="submit" value="提交">
</form>
public class Action1{
private Map<String,String> map;
//...省略getter/setter方法
public String hello1() {
System.out.println(map);
return "success1";
}
}
值栈(ValueStack)
- 栈:先进后出
- 队列:先进先出
struts拦截器
StudentAction.java
public class StudentAction {
public String getAdd() {
System.out.println("add");
return "success";
}
public String getUpdate() {
System.out.println("update");
return "success";
}
public String getDel() {
System.out.println("del");
return "success";
}
public String getSelect() {
System.out.println("select");
return "success";
}
}
MyInterceptor3.java
//自定义拦截器
public class MyInterceptor3 extends MethodFilterInterceptor{
private static final long serialVersionUID = 1L;
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
//前处理
System.out.println("before");
invocation.invoke();
//后处理
System.out.println("after");
//返回结果集,不执行后面的拦截器,直接给result处理结果集,跳转页面
return null;
}
}
<?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">
<!-- 1.配置拦截器 -->
<interceptors>
<interceptor name="myInterceptor3" class="com.bjlemon.interceptor.MyInterceptor3"></interceptor>
<!-- 2.配置拦截器栈 -->
<interceptor-stack name="myInterceptor">
<!-- 引入自定义的拦截器 -->
<interceptor-ref name="myInterceptor3">
<!-- excludeMethods,includeMethods只能出现一个 -->
<!-- 指定不进行拦截的方法 -->
<!-- <param name="excludeMethods">getAdd,getUpdate</param> -->
<!-- 指定进行拦截的方法 -->
<param name="includeMethods">getDel,getSelect</param>
</interceptor-ref>
<!-- 引入struts2的默认拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 配置默认的拦截器栈 -->
<default-interceptor-ref name="myInterceptor"></default-interceptor-ref>
<global-allowed-methods>getAdd,getUpdate,getDel,getSelect</global-allowed-methods>
</package>
</struts>
struts2的执行流程
- 用户请求前端控制器(StrutspreapredAndExecuteFilter),它是一个 Filter,拦截用户的请求,根据用户请求的url调用Action
- 前端控制器(StrutsPrepareAndExecuteFilter)判定该请求是否是一个Struts2 请求(ActionMapper)
- 若该请求是一个Struts2请求,则前端控制器StrutsPrepareAndExecuteFilter 把请求的处理交给ActionProxy
- ActionProxy创建一个ActionInvocation的实例,并进行初始化
- ActionInvocation实例在调用 Action 的过程前后,涉及到相关拦截 器(Intercepter)的调用。
- Action 执行完毕,ActionInvocation 负责根据struts.xml中的配置 找到对应的result,渲染结果。
- 执行各个拦截器 invocation.invoke() 之后的代码
- 把结果发送到客户端