Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。
JSP + JavaBean = Model1
JSp + Servlet + JavaBean = Model2(典型的MVC)
http://struts.apache.org/download.cgi#struts255
web.xml,只要和web应用整合,就要运用到这个文件
JSP+servlet+javaBean 就需要把servlet在web.xml中配置,当然,你也可以用注解的方式声明
web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>structs-timerdisplay-name>
<filter>
<filter-name>struts2filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
filter>
<filter-mapping>
<filter-name>struts2filter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<welcome-file-list>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
web-app>
struts.xml
The content of element type “package” must match “(result-types?,interceptors?,default-
interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-
mappings?,action*)”.配置的节点有先后顺序
<include file="structs-User.xml">include>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="action名称" class="类的路径com.peng.action.TimerAction">
<result>/success.jspresult>
action>
package>
struts>
配置 action 之后,可以通过路径后加入路径访问
http://localhost:8080/structs-timer/timer.action
http://localhost:8080/structs-timer/timer
其他的一些配置
<constant name="struts.devMode" value="true" />
<constant name="struts.action.extension" value="action" />
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="mytimer"
class="com.peng.interceptor.TimerInterceptor">interceptor>
interceptors>
<global-results>
<result name="inplut">/error.jspresult>
<result name="error">/error.jspresult>
global-results>
<action name="timer" class="com.peng.action.TimerAction">
<result>/success.jspresult>
<interceptor-ref name="defaultStack">interceptor-ref>
<interceptor-ref name="mytimer">interceptor-ref>
<param name="url">http:www.qq.comparam>
action>
package>
常量值
<constant name="struts.custom.i18n.resources" value="mess"/>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<constant name="struts.action.extension" value="do,go"/>
<constant name="struts.serve.static.browserCache" value="false"/>
<constant name="struts.configuration.xml.reload" value="true"/>
<constant name="struts.devMode" value="true" />
<constant name="struts.ui.theme" value="simple" />
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.multipart.maxSize" value="41943040"/>
在 web.xml 中配置的
<filter>
<filter-name>struts2filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
filter>
<filter-mapping>
<filter-name>struts2filter-name>
/*
filter-mapping>
在web项目启动的时候,过滤器就生效
2.1.3版本后
StrutsPrepareAndExecuteFilter,可以在执行action之前,添加自己的过滤器
TestServlet.java
//package com.peng.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
@WebServlet("/pppp")//注解的方式
public class TestServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("成功了到达action....pppp ");
RequestDispatcher rd = req.getRequestDispatcher("mypage.jsp");//跳转到mypage.jsp
rd.forward(req, resp);
}
}
另一种方式:注册servlet的方式
<servlet>
<servlet-name>TestServletservlet-name>
<servlet-class>com.peng.servlet.TestServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>TestServletservlet-name>
<url-pattern>/ppppurl-pattern>
servlet-mapping>
通过下面的路径访问
http://localhost:8080/ServletTest/pppp
Structs本来就是servlet的升级产品,控制Action的使用本来就是Structs的功能,因为Structs的拦截,直接访问servlet是不能成功的
一.修改web.xml 文件配置
原来是
<url-pattern>/*url-pattern>
修改为
<url-pattern>*.actionurl-pattern>
即不对action进行拦截
方法二
在struts.xml中的的节点下面添加struts2处理的请求后缀 常量:
<constant name="struts.action.extension" value="action" />
这样的话,每个 action 都必须加后缀 xxx.action,才能正常访问,当然你也可以设置其他的后缀,servlet也可以正常访问了
http://localhost:8080/structs-timer/TestServlet
http://localhost:8080/structs-timer/timer.action
http://localhost:8080/structs-timer/timer.action 不能访问
更多方法:http://blog.sina.com.cn/s/blog_7ffb8dd50101aw8l.html
如果这个路径可以
http://localhost:8080/struts2/helloworld.action
则
http://localhost:8080/struts2/aaa/bbb/helloworld.action
也可以
动态方法调用就是为了解决一个Action对应多个请求的处理时Action太多
一个Action就一个execute()方法,一个模块写一个action,action只有一个默认的execute()方法,那action多的不是上天了吗
三种方式解决
1.指定method属性
2.感叹号方式
3.通配符方式
建立一个action包,存放action,src下存放structs.xml.在WebContent下建立相应的jsp文件
action中加入了两个方法 add ,update,都返回SUCCESS
HelloWorldAction.java
//package com.struts2.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction extends ActionSupport {
public String add(){
return SUCCESS;
}
public String update(){
return SUCCESS;
}
@Override
public String execute() throws Exception {
System.out.println("执行Actoin");
return SUCCESS;
}
}
structs.xml文件中做相应的更改
..
name="helloworld" class="com.struts2.action.HelloWorldAction">
<result >/result.jspresult>
name="addAction" method="add" class="com.struts2.action.HelloWorldAction">
<result >/add.jspresult>
name="updateAction" method="update" class="com.struts2.action.HelloWorldAction">
<result >/update.jspresult>
..
http://localhost:8080/Struts2_Test/addAction 访问的是add.jsp
http://localhost:8080/Struts2_Test/updateAction 访问的是update.jsp
方法多的时候,也不方便啊,不推荐使用,看其他的
首先在structs.xml中开启一个常量
<constant name="struts.enable.DynamicMethodInvocation" value="true">constant>
更改struct.xml文件的action
name="helloworld_*" method="{1}" class="com.struts2.action.HelloWorldAction">
<result >/result.jspresult>
<result name="add">/add.jspresult>
<result name="update">/update.jspresult>
更改HelloWorldAction ,注意方法的return值要相应改变
public class HelloWorldAction extends ActionSupport {
public String add(){
return "add";
}
public String update(){
return "update";
}
@Override
public String execute() throws Exception {
System.out.println("执行Actoin");
return SUCCESS;
}
}
http://localhost:8080/Struts2_Test/helloworld.action 访问的是result.jsp
http://localhost:8080/Struts2_Test/helloworld!add.action 访问的是add.jsp
http://localhost:8080/Struts2_Test/helloworld!update.action 访问的是update.jsp
官方不推荐使用
关闭感叹号的方式,设为 false
<constant name="struts.enable.DynamicMethodInvocation" value="false">constant>
统配符的方式
name="helloworld_*" method="{1}" class="com.struts2.action.HelloWorldAction">
<result >/result.jspresult>
<result name="add">/{1}.jspresult>
<result name="update">/{1}.jspresult>
public class HelloWorldAction extends ActionSupport {
public String add(){
return "add";
}
public String update(){
return "update";
}
@Override
public String execute() throws Exception {
System.out.println("执行Actoin");
return SUCCESS;
}
}
http://localhost:8080/Struts2_Test/helloworld.action 访问的是result.jsp
http://localhost:8080/Struts2_Test/helloworld_add.action 访问的是add.jsp
当然action也可匹配多个
name="*_*" method="{2}" class="com.struts2.action.{1}Action">
<result >/result.jspresult>
<result name="add">/{2}.jspresult>
<result name="update">/{2}.jspresult>
http://localhost:8080/Struts2_Test/HelloWorld_add.action 访问的是add.jsp
大写的HelloWorld,因为是类的路径啊
..
ref name="index"> ref>
name="index">
<result>/error.jspresult>
<constant name="struts.action.extension" value="html">constant>
return 类型
配置Action
name="LoginAction" method="login" class="com.struts2.action.LoginAction">
<result >/success.jspresult>
<result name="input">/login.jspresult>
有类型转换等错误时(表单验证不正确),返回input,在登录界面登录时,还是会返回登录界面
User.java
//package com.struts2.po;
import java.util.List;
public class User {
private String username;
private String password;
private int age;
private List bookList;
//getter and setter
}
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="username"><%-- "username" > --%><br>
书籍1:<input type="text" name="bookList[0].username"><br>
书籍2:<input type="text" name="bookList[1].username"><br>
密码:<input type="password" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交"/>
form>
LoginAction.jsp
//package com.struts2.action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.struts2.po.User;
public class LoginAction extends ActionSupport
implements ModelDriven<User>{
private User user = new User();
public String login(){
System.out.println(user.getUsername());
System.out.println(user.getBookList().get(0).getUsername());
System.out.println(user.getBookList().get(1).getUsername());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
即使没有在 LoginAction 中,显式的声明格式类型错误,structs自动检测
显式声明校验条件
LoginAction.jsp
package com.struts2.action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.struts2.po.User;
public class LoginAction extends ActionSupport
implements ModelDriven<User>{
private User user = new User();
public String login(){
if(user.getUsername()==null
||"".equals(user.getUsername())){
this.addFieldError("username", "用户名为空");
return INPUT;
}
System.out.println(user.getUsername());
System.out.println(user.getBookList().get(0).getUsername());
System.out.println(user.getBookList().get(1).getUsername());
return SUCCESS;
}
@Override
public User getModel() {
return user;
}
}
运用structs的
标签显示全部错误信息
想显示特定指定的错误信息,如上文的this.addFieldError("username", "用户名为空");
则可以用
<s:fielderror fieldName="username"/>
<s:fielderror>
<s:param>usernames:param>
<s:fielderror/>
<%@ taglib prefix="s" uri="/struts-tags"%>
...
<form action="LoginAction.action" method="post">
用户名:<input type="text" name="username"> <s:fielderror >s:fielderror><br>
书籍1:<input type="text" name="bookList[0].username"><br>
书籍2:<input type="text" name="bookList[1].username"><br>
密码:<input type="password" name="password"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="提交"/>
form>
首先是类型检查,之后才是自己声明的校验
有很多时候一个< result>可供很多< action>使用,这时可以使用< global-results>标签来定义全局的< result>
<package name=".." namespace="/" extends="struts-default">
<global-results>
<result name="mainpage">/main.jspresult>
global-results>
package>
<result name="success" type="">/success.jspresult>
默认为 dispatcher 支持 JSP 技术
<package name="struts-default" abstract="true">
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<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"/>
<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>
package>
默认 dispatcher 跳转的方式请求不变–>可以去WEB-INF下面的页面
redirect 重定向—>请求发生了改变,不能去WEB-INF下面的页面
redirectAction 跳转到另一个Action下
plainText 查看原文
<action name="source">
<result type="plainText">
<param name="charSet">utf-8param>
<param name="location">/login.jspparam>
result>
action>