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

简介: Struts2的复习 开发struts2所需要的包 Struts2的启动配置 Struts2的配置文件是放在src的目录下,但是struts1的配置文件是放在WEB-INF的目录下 Struts2的struts.

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

   <result name="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内部的转换机制自动转换的,但是对于对象等复杂的类型就不能自动转换了,需要自己定义方式了。

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

相关文章
|
XML Java Apache
Struts2入门二 | 学习笔记
快速学习 Struts2入门二,介绍了 Struts2入门二系统机制, 以及在实际应用过程中如何使用。
Struts2入门二 | 学习笔记
|
XML Java 数据格式
Struts2【入门】(三)
这是Strtus的开山篇,主要是引入struts框架…为什么要引入struts,引入struts的好处是什么,以及对Struts2一个简单的入门….
181 0
Struts2【入门】(三)
|
XML Java 数据格式
Struts2【入门】(二)
这是Strtus的开山篇,主要是引入struts框架…为什么要引入struts,引入struts的好处是什么,以及对Struts2一个简单的入门….
196 0
Struts2【入门】(二)
|
XML 安全 Java
Struts2【入门】(四)
这是Strtus的开山篇,主要是引入struts框架…为什么要引入struts,引入struts的好处是什么,以及对Struts2一个简单的入门….
137 0
Struts2【入门】(四)
|
Java
Struts2【入门】(一)
这是Strtus的开山篇,主要是引入struts框架…为什么要引入struts,引入struts的好处是什么,以及对Struts2一个简单的入门….
139 0
|
XML 安全 Java
day25_day27_Struts2_学习回顾
day25_01_学习回顾    1、Struts2框架在三层架构中哪部分进行的再优化?    答:         表现层、MVC模式。2、Struts1和Struts2的一个显著区别是什么?    答:         Struts1的核心控制器是一个servlet。
1483 0
|
Java 前端开发 Spring
|
Java 前端开发
Struts2知识点学习笔记
写给自己的话 好记性不如烂笔头,不可能说看了一遍视频就可以完全掌握的。留下这篇笔记,便于今后的复习吧。 1、 访问ServletAPI 访问ServletAPI(response,request,)的三种方式: ActionContext方式 实现***Aware接口 ServletActionContext 2、Action的搜索顺序 以http://localhost:8080/struts2/path1/path2/path3/student.action为例。
1083 0
18.如何自学Struts2之Struts2标签和集成初略总结篇
18.如何自学Struts2之Struts2标签和集成初略总结篇[视频]   之前写了一篇“打算做一个视频教程探讨如何自学计算机相关的技术”,优酷上传不了,只好传到百度云上:   http://pan.baidu.com/s/1kTDsa95 有问题可以直接回复这篇文章。
1084 0