struts2初学小结

来源:互联网 发布:电子商务大数据 编辑:程序博客网 时间:2024/06/06 02:16

刚开始学习struts2的相关内容,小结一下。

首先说下环境的配置:

1.下载struts2.3.15.1,解压出apps/blank.war,这里面就是一个完整的实例,我们找到struts-2.3.15.1\apps\struts2-blank\WEB-INF\lib,把里面的jar文件都复制到你的web project工程的WebRoot\WEB-INF\lib里面,然后在struts2-blank\WEB-INF\classes里找到struts.xml,复制到src里就行了,这样基本的环境就配置好了。

看下我的:



    画了一个struts2的工作流程图:


以一个helloworld的例子来看。


struts2是一个控制流程的指挥者,Client 访问http://a.com/xxx/hello,Client的访问首先被tomcat接手,tomcat从URL中发现Client想访问xxx,那就找到xxx目录,定位到hello前看下xxx/WEB-INF/web.xml,在里面发现了过滤器,贴下web.xml的源码:

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>

既然有过滤器,而且过滤器<url-pattern>/*</url-pattern>,即所有访问都要先经过struts2这个过滤器,那就把Client的request交给struts2filter,它会在struts.xml里依次查找namespace、action,看下struts.xml代码:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd"><struts><constant name="struts.devMode" value="true" /> <!-- 开发模式 这样的话每次修改都会在浏览器立刻体现,而不用重启服务器 --><package name="default" namespace="/" extends="struts-default"><action name="*"><result name="success">/hello.jsp            </result></action></package><include file="example.xml" /><!-- Add packages here --></struts>

这里namespace为/,这个“/”对应xxx/目录,action name为* ,即所有访问都返回它对应result,一般写成
<result>/hello.jsp</result>

就可以使访问XXX/目录下所有的请求都返回hello.jsp,不过此时我写成

<result name="success">也可以,因为默认值就是success。

看下结果:


这是最简单的一个过程,中间没有经过action,正在学,学会了再加吧



-------------------------------------------------分割线----------------------------------------------

刚尝试写了一个简单的验证系统,login.jsp填写登陆表单,提交到userlogin这个action,struts.xml将这个请求提交给login.java这个action,并在提交的同时将username password 通过set方法传给action(甚至直接可以访问userlogin?username=123&password=123来传参),action判断用户名密码是否正确,然后将结果返回成一个string返回给xml,xml再根据配置返回对应的jsp。


(除此之外,还可以使用domain model传参,方法是这样:1建立一个user.java的model类,2.在action中不要写username password了,写一个User user = null;和他的setget方法,然后可以通过:userlogin?user.username=123&password=456传参 )

传参方面的知识介绍:

-----------------------细节分割线 开始-----------------------------

三种传参的方式:1.用action属性(get set) 2.用domain model 3.用model driver


传参包含中文的问题:要想传参包含的中文不成为乱码,应该这样:1.提交表单的JSP页面中设置提交方式为POST 2.在struts.xml里增加:

<constant name="struts.i18n.encoding" value="GBK"/>  这句话其实就是把action中的reuqest的字符集设置成了gbk      完毕。

-----------------------细节分割线 结束-----------------------------

login.jsp

<%@ page contentType="text/html; charset=UTF-8" %><%@ taglib prefix="s" uri="/struts-tags" %><html><head>    <title>Sign On</title></head><body><s:form action="userlogin">    <s:textfield key="username"/>    <s:password key="password" />    <s:submit/></s:form></body></html>


struts.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd"><struts><!--<constant name="struts.enable.DynamicMethodInvocation" value="false"/> <constant name="struts.devMode" value="true" /> <packagename="default" namespace="/" extends="struts-default"><default-action-ref name="index" /> <global-results> <resultname="error">/error.jsp</result> </global-results><global-exception-mappings> <exception-mappingexception="java.lang.Exception" result="error"/></global-exception-mappings> <action name="index"> <resulttype="redirectAction"> <param name="actionName">HelloWorld</param><param name="namespace">/example</param> </result> </action></package>--><constant name="struts.devMode" value="true" /> <!-- 开发模式 这样的话每次修改都会在浏览器立刻体现 --><package name="default" namespace="/" extends="struts-default"><default-action-ref name="index" /><action name="index"><!-- 默认 --><result>/hello.jsp</result></action><action name="userlogin" class="action.login"><result name="success">/loginsuccess.jsp            </result><result name="error">/error.jsp            </result></action></package><include file="example.xml" /><!-- Add packages here --></struts>

login.java

package action;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class login extends ActionSupport {private String username = null;private String password = null;String FORWARD = null;private HttpServletRequest request = ServletActionContext.getRequest(); // 获取requestpublic 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;}public String execute() throws Exception {request.setAttribute("username", username);if (username.equals("123")) {FORWARD = "success";} else {FORWARD = "error";}return FORWARD;}}

loginsuccess.jsp

<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>    <body>    用户:<%=request.getAttribute("username") %>登陆成功. <br>  </body></html>

------------------------------------------------继续深入学习--------------------------------------------------



0.struts.xml学习方法

(1)当我们不知道如何配置的时候可以打开struts-2.3.15.1\docs\WW\docs\home.html查询文档

(2)关于常量的默认配置我们可以打开struts2-core-2.3.15.1.jar\org.apache.struts2\default.properties这个文件,里面保存着xml里所有变量的默认属性 比如struts.i18n.encoding 我们可以修改哦

1.sturts.xml的package包配置

<package name="default" namespace="/" extends="struts-default"><default-action-ref name="index" /><action name="index"><!-- 默认 --><result>/hello.jsp</result></action><action name="userlogin" class="action.login"><result name="success">/loginsuccess.jsp            </result><result name="error">/error.jsp            </result></action></package>

如上,package有三个属性,name:必须的,包的名字,随便写,默认是default, extends:可选属性,指定包的父包,默认是struts-default,继承了这个包才能用Struts2的核心功能哦,namespace:可选,命名空间,默认是/ ,若为/或空,当无法精确定位到别的namespace时,都将访问这里的action。如果为/123 那么在原来的目录后加/123/即可访问

struts.xml的一些常量

 <!-- 该属性指定需要Struts2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。        如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 -->    <constant name="struts.action.extension" value="do" />    <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->    <constant name="struts.serve.static.browserCache" value="false" />    <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为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.i18n.encoding" value="UTF-8" />    <!-- 指定允许上传的文件最大字节数。默认值是2097152(2M) -->    <constant name="struts.multipart.maxSize" value="10701096"/>    <!-- 设置上传文件的临时文件夹,默认使用javax.servlet.context.tempdir -->    <constant name="struts.multipart.saveDir " value="d:/tmp" />


2.Action类文件

struts2的action不需要继承任何类和接口,比如struts1借用ActionForm获取表单数据,但struts2可以利用setter getter获得。虽然不是必须要实现接口或继承父类,但一般需要继承ActionSupport类或实现Action接口,重写execute()方法,因为action被调用时默认会调用这个方法。

(1)method属性

<action name="userlogin" class="action.login" method="login">

这时struts不再调用默认的execute方法,而是调用指定的login方法。

<action name="user_*" class="action.login" method="{1}">

这个更好用,当请求user_为前缀的action时,都将访问这个action文件,然后将后面的通配符作为方法名去调用,比如请求user_login,则会调用login.java的login方法

(2)action内获取request session的方法 

private HttpServletRequest request;public String execute() throws Exception {request = ServletActionContext.getRequest();return "success";}


3.简单数据验证

流程:login.jsp提交一个含有username的表单给 userlogin.java这个action,action判断用户名不是123时返回一个错误,并跳转回login.jsp

贴代码

login.jsp

<%@ page contentType="text/html; charset=gbk"%><%@ taglib prefix="s" uri="/struts-tags"%><html><head><title>Sign On</title></head><body><s:form action="userlogin"><s:fielderror name="user"/><!-- 这个标签可以用来显示错误信息 -->用户名<input type="text" name="username"/><s:fielderror name="pwd"/><!-- 这个标签可以用来显示错误信息 -->密码<input type="text" name="password"/><input type="submit" value="提交"/></s:form></body></html>

struts.xml

<action name="userlogin" class="action.userlogin"><result name="loginsuccess">/loginsuccess.jsp            </result><result name="input">/login.jsp            </result></action>

userlogin.java

package action;import javax.servlet.http.HttpServletRequest;import model.User;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;public class userlogin extends ActionSupport {String username = null;String password = null;String FORWARD = null;private HttpServletRequest request = ServletActionContext.getRequest(); // 获取requestpublic 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;}public String execute() throws Exception {if (getUsername().equals("123")) {FORWARD = "loginsuccess";} else {this.addFieldError("user", "username error!");//添加错误信息,前台jsp可以用 <s:fielderror fieldName="user"></s:fielderror>接受并显示FORWARD = "input";}return FORWARD;}}

3.2关于现实错误信息的细节:如果使用s:fielderror标签,jsp会为这个错误信息提供一个样式显示,如果jsp页面只想单纯的得到错误信息字符串的话,可以使用<s:property value="errors"/>,我们先在JSP页面中添加<s:debug></s:debug>,打开页面后会看到debug信息,在value stack中可以看到 error 对应的value即为错误信息"{user=[username error!], pwd=[pwd error!]} ",所以我们可以使用<s:property value="user"/>直接取到错误信息的值。另外,这个error是一个MAP,我们可以使用<s:property value="errors.user"/>直接显示[username error!],然后呢,这个信息是被方括号包含的 所以他是一个数组元素,那么我们如果写<s:property value="errors.user[0]"/>就会显示"username error!"


4.拦截器

这部分我是看http://www.blogjava.net/max/archive/2006/12/06/85925.html 学习的,详情看这里吧。

另外 可以通过  HttpServletRequest request = ServletActionContext.getRequest();获取request的参数


4.转换器

   当action的参数不是String 比如是Date的时候,我们无法直接给action提交参数(其实我觉得是可以给set方法写代码转换的),就可以使用转换器。

   转换器由转换类+properties文件构成,这里模拟一个转换Date的小程序:jsp提交date字符串给action包里的convertTest,DateConvert是转换类,xwork-conversion.properties是全局转换器的配置文件,里面的内容:需要转换的类途径=转换他的类途径,在这里就是:java.util.Date=action.DateConvert。


converttest.jsp

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%><html><body><form action="convertTest" method="get"><input type="text" name="date"><input type="submit" value="submit date"></form></body></html>

convertTest.java

package action;import java.util.Date;import com.opensymphony.xwork2.ActionSupport;public class convertTest extends ActionSupport {Date date = null;public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}public String execute() throws Exception {System.out.println(getDate());return "success";}}

DateConvert.java

package action;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Map;import ognl.DefaultTypeConverter;public class DateConvert extends DefaultTypeConverter {public Object convertValue(Map context, Object value, Class toType) {System.out.println("转化器被执行");if (toType == Date.class) {String[] str = (String[]) value;Date date = new Date(str[0]);return date;} else if (toType == String.class) {Date date = (Date) value;return date.toString();}return null;}}

xwork-conversion.properties 这个文件放到src目录下

xwork-conversion.properties


原创粉丝点击