`
ydbc
  • 浏览: 722106 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

Struts2学习之------>Struts2的详细的复习讲解

 
阅读更多

Struts2的复习

开发struts2所需要的包

Struts2的启动配置

Struts2的配置文件是放在src的目录下,但是struts1的配置文件是放在WEB-INF的目录下

Struts2struts.xml文件

<struts>

<!-- 这是 package里面有一个属性abstract如果设置为true,那么它下面不允许再写action-->

<!--name是为每个action取一个唯一的名字(因为可能下面有action需要继承它),千万记得namespace必须以’/‘开头, 但是name不需要,class是action的类名,method是处理请求的方法,来访问这个action的路径是namespace + action的name 即:/go/test -->

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

<action name="test"class="com.actions.FirstAction"method="getFirstAction">

<result name="success">/WEB-INF/page/success.jsp</result>

</action>

</package>

</struts>

启动struts2web.xml里面的过滤器

<filter>

<filter-name>struts2</filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

<!--org.apache.struts2.dispatcher.FilterDispatcher这是2.13以前的版本-->

</filter>

<filter-mapping>

<filter-name>struts2</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

解决struts.xml文件里没有提示的问题?

首先window-->Preferences然后在文本框中打xml查找,看到的下拉里表下找到xml catalog点击右边的add然后在弹出的文本框中,在location寻找struts-2.0.dtd的文件, key Typeuri,在key中写上http://struts.apache.org/dtds/struts-2.0.dtd这是在struts.xml的配置文件中中有这句代码。

Action名称的搜索顺序

举一个例子:

Struts2的默认访问后缀是以.action结束的。

假如你的url = "http://127.0.0.1:8080/firstStruts/go1/go2/go3/test";首先是去查找/go1/go2/go3结束的,如果不存在就去查找/go1/go2如果还找不到就去找/go1还找不到,就去找找默认的package,然后到默认的包里面去查找那个action如果找不到页面就会报炸不到action的错误!

不懂仔细看上序的那张图

<struts>

<!-- 这是 package里面有一个属性abstract如果设置为true,那么它下面不允许再写action-->

<!--name是为每个action取一个唯一的名字(因为可能下面有action需要继承它),千万记得namespace必须以’/‘开头, 但是name不需要,class是action的类名,method是处理请求的方法,来访问这个action的路径是namespace + action的name 即:/go/test -->

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

</package>

<!-- 默认的命名空间就是不设置namespace或者设置namespace="" -->

<packagename="it"extends="struts-default">

<actionname="test"class="com.actions.FirstAction"method="getFirstAction">

<result name="success">/WEB-INF/page/success.jsp</result>

</action>

</package>

</struts>

Action配置中的一些默认项

<!--action中的class默认值是com.opensymphony.xwork2.ActionSupport, method的默认方法是execute,result中的name的默认值是success,在execute方法中默认返回的值是seccess -->

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

<action name="firstAction">

<result>/WEB-INF/page/addUser.jsp</result>

</action>

</package>

Action中的result的各种转发类型

Dispatcher(这个相等于转发,也是默认的)redirect(这个是重定向)、redirectActionplainText

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

<action name="secondAction"class="com.actions.FirstAction"method="getFirstAction">

<!-- 就算是redirect,重定向的页面也必须以'/'开头 ,这是往地址栏中传递参数,参数就是在action中的一个属性的值-->

<result name="success"type="redirect">/success.jsp?userName=${userName}</result>

</action>

</package>

页面需要进行解码

<%

//因为传递过来的是经过编码后的汉字,所以必须解码才能够进行输出,否则会出现乱码

%>

${param.userName }

//这是action进行的编码

userName = URLEncoder.encode("曹欢","utf-8");

//这是解码的类URLDecoder

<%=URLDecoder.decode(new String(request.getParameter("userName").getBytes("iso8859-1"),"utf-8"),"utf-8")

//因为是重定向,所以不能得到保存在request作用域的值

//${userName };

%>

关于dispatcherredirectredirectActionplainText这四个属性,有很多知识,视屏是struts2的第六个,在struts中也有这个例子。(这个例子里面讲了很多东西,有很多细节啊)

<action name="injectFirstAction"class="com.actions.RegistAction"method="execute">

<!-- 这是为action的某个属性注入值 -->

<paramname="injectMessage">我的名字叫曹欢</param>

<resultname="success">

/success.jsp

</result>

</action>

Struts中的常量

在struts2中配置常量的,可以再struts-defaultstruts-plugin.xmlstruts.xmlstruts.propertiesweb.xml中配置常量,但是如果配置常量重复的话,那么后面的配置文件中的相同的常量会覆盖前面配置的常量。

一些常用的常量的配置

<!--这是控制request的编码 -->

<constant name="struts.i18n.encoding" value="utf-8"></constant>

<!--这是修改struts2的访问路劲的修改,如果要有几种方式,则value ="do, action" -->

<constant name="struts.action.extension" value="do"></constant>

<!--这是浏览器是否包村静态页面的缓存 -->

<constant name="struts.server.static.browserCache" value="false"></constant>

<!-- 这是修改配置文件后是否自动读取配置文件 -->

<constant name="struts.configuration.xml.reload" value="true"></constant>

<!-- 开发模式下可以打印更多的错误性信息 -->

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

<!-- 这是关于默认的试图主题 -->

<constant name="struts.ui.theme" value="simple"></constant>

<!-- 这是有spring来管理action --><!--注意这要在加载spring与struts2的包时才可以使用 -->

<constant name="struts.objectFactory" value="spring"></constant>

<!-- 这是动态的struts2是否支持动态调用 -->

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

<!-- 这是文件上传的大小的指定,是所有的文件大小的指定,如果是几个文件,只得是几个文件的大小加起来的大小 -->

<constant name="struts.multipart.maxSize" value="10701096"></constant>

<!--定义全局范围的资源文件-->

<constant name="struts.custom.i18n.resources" value="基名"></constant>

Struts的流程图

Struts2struts1的最大不同就是它的每个请求就会创建一个action,就是线程安全的,但是struts1是单实例是线程不安全的。Struts1创建了一个action然后把它保存在内存中,每次访问都是拿出内存的那个action

<includefile="这里填写配置文件的名字"></include>

Action的动态方法的调用

假如你系那个进入action的某个方法,可以再地址栏中

http://127.0.0.1:8080/struts2-2/injectAction/injectFirstAction!execute.action这样你进入的就是execute方法

http://127.0.0.1:8080/struts2-2/injectAction/injectFirstAction!add.action这样你进入的就是execute方法这样你进入的就是add方法

但是这种方式struts2的文档已经建议不使用,可能在以后的版本中就会取消

但是如果你加上一个常量的设置,这种 方式就不能使用

<!-- 如果设置为false,这是禁止动态方法的调用 -->

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

也可以采用通配符来进入到action的某个方法

<!-- 使用通配符来判断进入到action的哪个方法 -->

<packagename="injectPackage"extends="struts-default"namespace="/injectAction">

<!-- 这里的action的name使用了通配符,表示的就是进入到action的通配符的那个方法里面,后面的method就指名了,第一个通配符就用{1}来表示,因为通配符可以使用几个啊!在下面的class、result的值中都可以使用通配符 -->

<!-- 只要在访问的路径中的injectFirstAction_add表示的就是进入到add方法中 -->

<actionname="injectFirstAction_*"class="com.actions.RegistAction"method="{1}">

<!-- 这是为action注入值 -->

<paramname="injectMessage">我的名字叫曹欢</param>

<resultname="success">

/success.jsp

</result>

</action>

</package>

页面:

表示的是进入到add方法中

<ahref="${pageContext.request.contextPath}/injectAction/injectFirstAction_add.action">click</a>

Action接收请求参数

这是关于请求参数的接收,在struts2中有这个例子

假如页面有一个关于生日的文本框,它写的格式是1990/09/09这样在action就不能这样接收,

这时候就需要一个转换器,局部转换器只能对该包下的类中的属性进行转换。

定义局部转换器的步骤:1、首先些一个转换器的类。需要继承一个转换器的类。需要实现它的convertValue的方法。

public class DateConvertextends DefaultTypeConverter{

//第一个参数是关于ongl的一个上下文, value是传进来的目标值,toType是要转换成的类型

public Object convertValue(Map<String, Object> context, Object value,

Class toType) {

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");

System.out.println("asdasd");

System.out.println(toType);

if(toType == Date.class)

{

String [] s = (String [])value;

String s1 = s[0];

try {

return simpleDateFormat.parse(s1);

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

else if(toType == String.class)

{

System.out.println("caohuan");

Date date = (Date)value;

System.out.println(date);

return simpleDateFormat.format(date);

}

else

{

return null;

}

return null;

}

}

2、然后对要转换的那个action中的某个属性进行配置。在要转换的那个属性的action的包下写一个类名-conversion.properties的文件。然后对要转化的属性进行配置:birthday = 转换器的类全名。请看struts2的这个例子

全局转换器与局部转换器的不同:

1、需要把转换器的配置文件放在src的目录下。

2、需要配置文件中的那个转换的类型改成具体的类型:如;如果你是转换date类型的数据:java.util.Date = 转换器的类全名。

3、需要把配置文件的名字改为xwork-conversion.properties

怎样在action的方法的各个作用域中添加属相,主要是ActionContext这个类

ActionContext actionContext = ActionContext.getContext();

actionContext.put("a","这是request作用域的范围");

actionContext.getSession().put("b","这是session范围的作用域");

actionContext.getApplication().put("c","这是application范围的作用域");

如果我非要等到各个作用域怎么办?

//这是得到request

HttpServletRequest request = ServletActionContext.getRequest();

request.setAttribute("caohuan","1111");

HttpSession

//这是得到session

session = ServletActionContext.getRequest().getSession();

session.setAttribute("huangwentao","222");

//这是得到servletContext对象

ServletContext context = ServletActionContext.getServletContext();

context.setAttribute("xiaohua","333");

一个小的知识点:actionContext.put("arr", Arrays.asList("go1","go2","go3"));这是王request对象中存储集合list

单文件上传

有这个例子的详细代码

一个细节:在IE6中的文件上传中可以自己书写地址,但是在IE的后面版本不可以,在其他的浏览器里面不可以写。

也有多文件上传的例子

这里也有文件下载的例子,特别经典。

action的方法进行校验

手工书写对所有的action方法进行校验

1、action需要继承ActionSupport,然后重写validate方法

public void validate() {

if(userName ==null ||"".equals(userName.trim()))

{

//这是将错误保存起来

this.addFieldError("userNameError", "用户名不能为空");

}

if(mobile ==null ||"".equals(mobile.trim()))

{

this.addFieldError("mobileError", "电话号码不能为空");

}else

{

//这是匹配器匹配电话号码

if(!Pattern.compile("^1[358][0-9]{9}$").matcher(this.mobile).matches())

{

this.addFieldError("mobileError", "电话号码书写不正确");

}

}

}

2、如果出现表单验证错误,需要跑到错误页面,需要配置input

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

<action name="validate_*"class="com.actions.ValidateAction"method="{1}">

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

<!-- 这里的input表示的是如果验证出现错误就跑到错误页面 -->

<result name="input">/index.jsp</result>

</action>

</package>

3、在页面显示错误,用<s:filedError>来显示错误

<formaction="${pageContext.request.contextPath}/test/validate_update.action"method="post">

<inputtype="text"name="userName"/><s:fielderror fieldName="userNameError"/><br/>

<inputtype="text"name="mobile"/><s:fielderror fieldName="mobileError"/><br/>

<inputtype="submit"value="提交"/>

</form>

action的制定方法进行校验

对action中的某个方法进行校验(手写的代码)只需要在对action中的所有的方法进行校验的基础上在validate的后面加上要校验的方法名。记得方法名的第一个字母要大写

//这是对action的所有方法全部进行校验,如果在validate的后面加上方法的名字,那么就只对action的这个方法进行验证,记得方法名的第一个字母要大写

public voidvalidateUpdate() {

if(userName ==null ||"".equals(userName.trim()))

{

this.addFieldError("userNameError","用户名不能为空");

}

if(mobile ==null ||"".equals(mobile.trim()))

{

this.addFieldError("mobileError","电话号码不能为空");

}else

{

//这是匹配器

if(!Pattern.compile("^1[358][0-9]{9}$").matcher(this.mobile).matches())

{

this.addFieldError("mobileError","电话号码书写不正确");

}

}

}

校验器的流程

系统有一个fieldErrors

首先页面的form表单的字段传递进来(是通过类型转换器进行转换的),如果在转换的过程中出现错误(也就是有的字段不能转换),那么就会把转换错误保存到fieldErrors中,不管是否转换正确,都会进行下列步骤。

然后进入到要校验的方法,首先进入的是校验action某个方法的校验器,然后再进入到校验action中所有方法的校验器。如果在这个过程中出现错误,那么就会跑到input指向的错误页面,如果没有出现错误就会跑到result指向的页面。------>在这个过程中一定得注意,因为当类型转换器出现错误的时候也会将错误保存到fieldErrors中,所有即使在后面的校验器中没有出现错误,也会跑到input指定的页面。

基于xmlaction中所有的方法进行校验

收先是写一个配置文件,名字就是这个类的类名+validation.xml, 然后在xml文件中配置一些校验器(系统写了很多校验器),这些校验器在<!-- 这是struts的校验器,这些校验器在xwork-core的com.opensymphony.xwork2.validator.validators包下的default.xml有很多校验器,可以自己去看看 -->至于xml文件中的具体可以参看这个例子

<validators>

<fieldname="userName">

<field-validatortype="requiredstring">

<paramname="trim">true</param><!-- 这个设置是默认的 -->

<message>You must enter a name</message>

</field-validator>

</field>

<fieldname="mobile">

<!-- 这是struts的校验器,这些校验器在xwork-core的com.opensymphony.xwork2.validator.validators包下的default.xml有很多校验器,可以自己去看看 -->

<field-validatortype="requiredstring">

<paramname="trim">true</param>

<message>you must enter a mobile</message>

</field-validator>

<field-validatortype="regex">

<paramname="trim">true</param>

<paramname="expression"><![CDATA[^1[358]\d{9}$]]></param>

<message>you must enter a legal mobile</message>

</field-validator>

</field>

</validators>

如果在校验的xml文件中没有提示咋办

关于校验器

校验器visitor的用法

visitor校验器是校验Action中的复合类型属性。

1.定义UserInfo.java

public class UserInfo {

private String name;
private String location;

注:有以上两个属性的get/set方法。
}

2.Action定义:

private UserInfo user;
注:Action中有userget/set方法。

3.JSP写法:

<s:textfield name="user.name"></s:textfield>

4.校验文件配置:

1>.基本校验文件:
<field name="user">
< field-validator type="visitor">
< param name="context">userContext</param>
< param name="appendPrefix">true</param>
< message>测试:</message>
< /field-validator>
</field>

2>.复合类型校验文件:
<field name="name">
< field-validator type="requiredstring">
< message>姓名必须输入!</message>
< /field-validator>
</field>

<field name="location">
< field-validator type="requiredstring">
< message>籍贯必须输入!</message>
< /field-validator>
</field>

注:1>.复合类型校验文件命名:UserInfo-userContext-validation.xml
2>.复合类型校验文件位置同UserInfo.java在同一目录下。

用xmlaction中的某个方法进行验证

Xmlaction中某个方法进行校验值需要在上序的基础上将配置文件改一下。Action的类名-action的某个方法-validation.xml action的某个方法指的是struts中的actionname属性,只不过要把*改为具体的方法名。有这个例子

Xml校验的特点

好好看一下,关于校验的很多特点,值得学习。

总结:不管你是用手写代码的方法验证还是用xml验证,总之验证的action一定得继承actionSupport

全局范围的国际化

Action必须继承actionSupport

首先写两个国际化的资源文件

然后在再struts.xml文件中读取国际化资源文件,value是国际化资源文件的基名

<constantname="struts.custom.i18n.resources"value="itcast"></constant>

在页面里面读取资源文件里面的内容:<s:textname="go"></s:text>name是国际化资源文件里面的键值对的键。

action里面读取资源文件里面的值System.out.println(this.getText(go));

go是国际化资源文件里面的键

输出带有占位符的国际化资源文件

如果页面要输出的话:

<s:text name="go">

<s:param>caohuan</s:param>

<s:param>study</s:param>

</s:text>

如果是action中要出入值的话:字符窜数组是往国际化资源信息里面填充值

this.getText("go",new String[]{"caohuan","study"})

在包范围的国际化资源信息

就是在action的包下配置国际化资源文件,package_语言_国家

如果只是读取包下的国际化资源文件里面的内容,那么不需要

<constantname="struts.custom.i18n.resources"value="itcast"></constant>这句代码也可以读取的到,但是如果在包下的资源文件里面读取不到信息,就会跑到全局范围的国际化资源文件里面读取内容,但是像在index.jsp是读取不到包下的国际化资源文件里面的内容的,所以必须读取全局范围国际化资源文件里面的内容

Action范围的资源文件

就是在actionl类的写上action的资源文件,命名规则:类的名字_语言_国家

TestAction_zh_CN.properties

不进行任何配置,直接读取配置文件下的资源文件

<!-- 这是从全局范围内读取国际化资源文件,在struts.xml的配置文件里面可以不写<constant name="struts.custom.i18n.resources" value="itcast"></constant>这句代码 -->

<s:i18nname="itcast">

<s:textname="go">

<s:param>caohuan</s:param>

<s:param>study</s:param>

</s:text>

</s:i18n><br/>

<!-- 这是从包中读取国际化资源信息 -->

<s:i18nname="com/actions/package">

<s:textname="go">

<s:param>caohuan</s:param>

<s:param>study</s:param>

</s:text>

</s:i18n><br/>

<!-- 这是从action中读取国际化资源信息 -->

<s:i18nname="com/actions/TestAction">

<s:textname="go">

<s:param>caohuan</s:param>

<s:param>study</s:param>

</s:text>

</s:i18n>

Ognl表达式,可以好好看看ognl的那个视频。里面的东西很重要,重要的是要懂得原理

标签

Property属性

Iterator标签

<s:set>标签

<s:url>标签

<scheckBoxList>标签

<s:radio>标签

<s:select>标签

防止表单重复提交

Ssh2整合所需要的包:

枚举类型的映射

Ssh2的整合其实也很简单,hibernatespring的整合与以前一样,只不过当spring管理action的时候用的是<constant name="struts.objectFactory" value="spring"></constant>

<constant name="struts.action.extension"value="do,action"></constant>

<constant name="struts.objectFactory"value="spring"></constant>

<packagename="caohuan"extends="struts-default"namespace="/test">

<!-- 下面的class是在spring中实例化的action的名字 -->

<actionname="go_*"class="testAction"method="{1}">

<resultname="success">/success.jsp</result>

</action>

</package>可以看这个例子

浪溪的那套视频的讲解笔记

1、怎么将我们的struts2的源文件编程我们的css/html格式的帮助文档?

因为我们的struts2没有css/html格式的帮助文档?

首先将建一个javaProject,然后将虽有的.java的文件复制到src下(这些java文件就是我们struts的核心库的源文件,我的电脑的路径:D:\终极复习版\struts\struts2的综合\struts2的一些包\struts-2.3.1.2-all\struts-2.3.1.2\src\core\src\main\java),这里会出现没有导入包的错误,然后将所有的struts2依赖的包导入进去,然后点击prohect的菜单---->generate javadoc---->然后进入到下面的页面,注意下面的选中部分,一定要是我们的jdkbin文件下的javadoc.exe

Destination是将我们的文件导入到那个文件

Document title是文档的名字,选中所有的文件,然后点击下一步下一步就可以完成了

2、类型转换的讲解

Struts2对于八种基本类型及常用的stringdate类型这行都是能够用struts内部的转换机制自动转换的,但是对于对象等复杂的类型就不能自动转换了,需要自己定义方式了。

上面的讲解中有详细的讲解

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics