技术中心

这里象征着我们的态度和能力

Struts2的配置
作者:admin    来源:本站原创    发布时间:2012-04-27      浏览次数:14155
分享到:

步骤1.导入最基本的jar

sturts2-core-2.x.x.jar:   Struts2框架的核心类库

xwork-2.x.x.jar:      Xwork类库,Struts2在其上构建

ognl-2.6.x.jar:     对象导航语言,Struts2框架通过其读写对象属性

freemarker-2.3.x.jar:   Struts2UI标签的模版使用Freemarker编写

commons-logging-1.1.x.jar:   ASF出品的日志包,Struts框架使用这个日志包来支持Log4jJDK1.4+的日志记录。

commons-filetemp-1.2.1.jar:  文件上传组件,2.1.6版本后必须加入次文件

commons-io-1..3.2.jar 文件上传下载需要

步骤2.struts.xml放到src

struts.xml配置

代码:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

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

    <constant name="struts.devMode" value="false" />//struts.xml文件修改后是否立即生效 

    <include file="example.xml"/>

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

        <default-action-ref name="index" />

        <action name="index">

            <result type="redirectAction">

                <param name="actionName">HelloWorld</param>

                <param name="namespace">/example</param>

            </result>

        </action>

    </package>

    -->

    <!-- Add packages here -->

<constant name="sturts.i18n.encoding" value="GBK"/>

<!作用:官方宣称中文不乱码,但是还有乱码貌似->

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

<!作用:修改后不用reload-->

    <package name="b" namespace="/ab" extends="struts-default" >

        <action name="*" class="www.baidu.com.Hello2" method="{1}">

            <result name="fuckyou">

                /Hello2.jsp

            </result>

            <result name="fuck">

            /Hello.jsp

            </result>

        </action>

    </package>

</struts>

(绿色是保留部分一边copy,不起作用,红色是修改重点)

步骤3.web.xml放到webroot下的WEB-INF文件夹

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

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

注意struts2.xml 被读取后,将以javabean的形式存放在内存中,以后struts2对每个用户的每次请求处理将使用内存中的数据,而不是每次都读取struts.xml文件了

文件所在

这些 struts.xml 和 web.xml可以在struts-2.1.8.1appsstruts2-blank-2.1.8.1WEB-INF下找到struts.xml和 web.xmljar

Action注意事项

更改jsp编码

Window  -> Perference -> JSP(搜索Encoding为 Chinese nation stander

复制struts2项目时注意

Copy后的项目 -> Property ->web(搜索修改context-root 为“/项目名”

Struts.xml增加文件中的提示

由于xml文件,是根据dtd文件来显示的,而dtd文件并不为MyEclipse所知道,所以要手动的指定dtd所在的位置。

属性中 搜索 catalog (登记)

strutsuri复制到key

Location是那个Struts-2.0.dtd文件的位置(这个文件可以在libstruts2-core-2.1.8.1.jar解压后找到

Ok即可

Struts的运行机制

任何的运行机制都要从访问的网址开始:

例如:

http://localhost:8888/Struts2Test/hello

首先Tomcat会去寻找Struts2Test这个web站点,然后在这个站点中查看web.xml的配置

发现配置如下:

。。。。

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

。。。。

他用/*来匹配所有的访问,则filter调用doFilterdoFileter要参考struts.xml,因此找到struts.xml

查看struts中的namespace/,再在namespace为“/”之后查看有没有helloaction,有就直接输出result

NameSpace

namespace 是为了较少繁琐的定义路径而设置的

namespace如果不写,就是默认为空 :namespace=””;

如果为空,则namespace匹配所有的urlnamespace。类似*号一样。

例如:http://localhost:8888/1/2/3/4/hello

/1/2/3/4就是可以被空的namespace所匹配。

package java中的package相似,这里的主要功能是 在 继承的时候要用的packagename属性,还有用来区分相同的名字。

如果一个 package被定义为abstract,则这个包只能被继承,不能定义任何的action

路径问题1namespace路径问题)

如果访问的路径中的namespaceStruts.xml没有相对应的namespace,则就交给Tomcat去找web.xml是否有相应的设置,如果有就使用    例如:

<welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list> 就根据它来显示了(其实我试过很过都不行,只有部分可以)

路径问题2(相对和绝对路径问题)

这里要注意:要全部使用绝对的路径,否则会有问题:

问题例子:

如果你的namespace设置为:/rotoy要访问的actionhello,hello显示的页面为hello.jsp, index.jsphello.jsp是同一目录,都在WebrRoot下面。

hello.jsp中有一个连接为:<a herf=index.jsp> 跳往index.jsp</a>

URL为:http://localhost:8888/rotoy/hello访问正常,

但是如果点击hello.jsp中的连接,前往index.jsp的时候就出现错误了,找不到页面!

分析:hello.jspindex.jsp在同一个目录下面,应该用那个相对路径可以访问的,那为什么出现错误呢?

原因是:由于程序只知道的是当前的路径,你访问的是hello.jsp 则当前的路径是:

http://localhost:888/rotoy,如果你直接点击那个相对路径,则就访问了http://localhost:8888/rotoy/index.jsp页面了,它是在当前的目录寻找,所以就出错了,所以那个连接最好是设置为绝对路径

Action 学习内容简要回顾

实现一个Action3种方法

1.直接定义一个普通类,有一个返回String类型的execute方法

2.实现Action接口(ActionSupport也是实现此接口)

3.继承ActionSupport接口(最常用,开发时候只用它,

原因:

它封装了许多方法,实现它可以用它的方法

struts2 调用每个action的类的时候是new一个出来,不是像struts1一样,用相同的一个,这样就避免了线程同步的问题。

查看ActionSupport的源码

如果一个ation没有写class属性,则默认执行的是AtionSupport这个类,这个类用到了另外的一个框架->xwork

如果要看ActionSupport的源码,必须要给xwor-2.1.X.jar文件附加源码

ActionSupport也是执行的是 execute方法,返回success

ActionSupport实现了Action接口

DMI 动态方法调用(Dynamic Method Invocation)

运用感叹号(!)于Action后面来调用AcitonClass属性所指向的类中的方法

如:http://localhost:8888/T/abc/abc!text?name=abc&age=20

解:其中T为一个站点

第一个abcnamespace

第二个abcaction

textaction类中的一个方法

nameage是向ation类中传递的2个参数

age会自动的在intString中转换

注意:struts.xml中配置的文件中的<action>我们要把它和那个他对应的那个类想成同一个,因为那个类也是一个action,他们指的是同一个的不同映射结果!不要把它想成:配置文件中的action,然后这个action对应一个类! 不知这样的!他们是同一个!

通配符

例如:

<action name=student* class=com.baidu.www.count method={1}>

<result>

/ShowResult.jsp

</result>

</action>

如果访问:http://localhost:8888/Student/studentadd

那么student就匹配了studentadd , *部分就匹配了add

{1}代码第一个*,{2}代表第二个*……

那么method=add了,就是*匹配了add

 

注意!匹配顺序:

先匹配最精确的action(就是最符合,最相像的)

带有*号的属于同一级别,谁前谁的优先级别大。

Action 接收参数的方法

例如:访问的地址为:http://localhost:8888/T/abc/count!add?name=abc&age=3

则:count action Mappingclass 中接收:

1用属性接收

1解:

在传递的属性很少时,用属性接收

具体:要在class中定义好nameagegettersetter

Struts2会自动的调用并且赋值,我们直接调用nameage即可

例如:访问的地址为:http://localhost:8888/T/abc/count!add?man.name=abc&man.age=3

2DomainModel接收

所谓的DomainModel就是一个DAO(应该是吧),用来传输数据中一个容器类

2

可在传递的属性比较多时使用

定义一个DomainModel(另一个类,如man类)

里面定义好属性(nameage),和属性的gettersetter方法

class中定义好这个DomainModel(即man不初始化),和mangetter setter方法

Struts2会自动的设置这个manname age 属性,我们调用即可

URL来给于参数,调用的URL

http://localhost:8888/rotoy/add!man.age=22&&man.name=Rotoy

注意:action类中要有mangettersetter方法

man中要有agenamegettersetter方法

中文参数问题

如果Struts提交的参数是中文会有乱码

官方解决:

其中的

是官方的解决方案。

配置方法,参看default.properties

简单的参数验证

例如:class中的name属性接收时不满足条件

由于Struts中的class没有request等的对象,所以只能

class中调用:this.addFieldError(name,Error msg);

JSP中接收

1先在顶端加:<%@taglib uri=/struts-tags prefix=s %>

2调用 <s: filed error fielName=”name theme=simple />

<s.property value=errors.name[0]/>

<s.debug></s:debug>//显示debug信息

<s:property></s:property>的作用是专门去取得:

Stack Context (也叫Action Context

中的值

Value Stack中放的是:错误信息和 Action 类中的属性。

其中

中的:

其中[]是指的数组,{}指的是:map类型的,{[]}明显是就map中的数组。

Action访问Web元素方法1

Action将要取得:

便于记忆

其中有 requestmap类型),和 sessionmap类型),applicationmap类型)放在value context中(也叫Action context,其实是ThreadLocal对象,ThreadLocal就是一个Thead和其值)

而 Action 中的属性是放在 value Stack 中的。

这就类似于jsp:他的page相当于value satck中的属性,其他的requestsessionapplicationAction 的一一相对应,这样便于记忆。

获取actionweb元素:

单态模式:例如:ActionContext.getContext.get (request);

其中:ActionContext是静态引用, ActionContext.getContext是获得Action Context(Value Context)的实例。

ActionContext.getContext.get(request)是根据key获得request,还可以获得session,和Accpplication

方法分别为:

(由于取得的方法不同,所以只有request要强转)

获取后可以在Action中使用:

Jsp中可以取得:

关于:<s:property value=#request.r1/>的写法

由于有说明:

所以可以用#来取值。(value stack 中的直接取得,不用#

注意细节:

action中的request session application 都是map类型的,在jsp页面中可以取得,说明Struts在这个过程中,已经将 action中的map类型的web 元素,完全复制到了 jsp中的HttpRequsest,  HttpSession  HttpApplication中了

Action访问Web元素方法2

Ioc或者DI最常用

Invers of Control (控制反转)

Dependency Injection(依赖注入)依赖struts2

解释:都是将自己的属性交给别人来操作,所以依赖别人,叫DI

有因为交给别人操作是把控制权交给别人,所以是IoC

Action实现了RequestAware ,SessionAware,ApplicationAware这些接口,然后重写里买呢的

setRequest(),setSession();setApplication()方法。就可以获得他们了

tip:其实真正开发reuqest几乎不用去获取,因为action的值会自动的放在value stack里面,

value tack又是在request里面!

application也不用,需要长久的话用数据库,或者放在一个类中。

之前都是maprequest等,

如何获得真实HttpRequest呢?

如图:(因为几乎不用,所以只给图代码)

方法1

方法2

总结访问web元素

访问Map类型
a)IoC(反转控制)(主要方法)

b)依赖Struts2

2访问原始类型(真实类型)

a)IoC(反转控制)

b)依赖Struts2

模块包含

如:

<struts>

<include file=login.xml/>//完全复制login.xml内容到这里

</struts>

这样是为了分工合作比较好。

 

默认Action

当输入的action不存在时,都转向这个action

Result的类型

注意:type=chain时候的result是指向action的,前面不要加/

默认是 dispatcher: forward)服务器跳转(只能跳转页面,不能是action(就这2个常用)

redirect: 客户端跳转(只能跳转页面,不能是action(就这2个常用)

chain服务器跳转action (了解即可)

redircAction客户端跳转action(了解即可)

freemarker跳到freemarker页面(后面讲)

httpheader: 发送头信息(不用)

stream:下载(后面讲)

velocity: freemarker类似的模版框架(抛弃,freemark超过它)

xslt:xml相关的xml语言(不用)

plaintext:将页面源码显示出来(不用)

tites页面分成几块(不用)

resultchain或者redircAction时候跳转其他包的action

<param name/>来指定

全局的resultpackageexends

如果每个action都有一个相同的action,都写麻烦,用global-result

只要配置了这个global-result,这个package的每个action不用写,都有了

那其他的包要用extends来继承这个包的配置,这个继承是继承那个包的所有的配置,所以包括了那个全局结果集

动态result

struts.xml文件中可以用${属性名}来获取value stack中的值。

不要和 el 表达式混淆,el是用在jsp中的

如果在action中将这个变量r根据情况设置,那么就是动态的结果了。

不同Action 的 value Stack

一次request就一个value stack,如果这时从一个action forward 到另一个action上,则他们共享一个value stack,因为forward不会发起新的request

那客户端跳转,这个action该如何将上次的值传给?

我们知道,如果是服务器跳转,直接在那个跳转的jsp页面的value stack中拿就可以了,

但是这里是客户端跳转,该怎么办呢?

答案是:将值取出,作为动态参数传给客户端跳转的那个界面

OGNL取值

Action中的domain Model 要自动的被struts 初始化的条件:

1:必须给actiondomain Modle传值。

2:必须要有无参构造函数。

aciondomain Model 传值:xxx/?user.age=99

它就就调用了无参构造,所以要有无参构造函数

OGNL是为了方便取得value stack 而设置的,所以它都是写在<s:property></s:property>之中

访问本action属性内容:

<s:property value=cat.friend.name></s:property>:action中有一个cat类,它有一个成员也是一个frienddog类,访问dog的名字。

如果要访问静态的:

前提是要配置,默认是false

访问本action静态属性

都是在类和方法或属性前面加@

还有一种只能访问Math类的方法:

访问 构造方法:(也就是创建对象)

OGNL访问集合对象

其中数组也是根据下标来访问的。

Set不能用下标,因为set的无序的。

OGNL取值投影

所谓投影就是过滤:

投影就3中过滤方式:?#^#,$#

#:代表条件

^#:代表最前面的一个

$#:代表最后面的那一个

this代表的是,当前遍历的那个对象,注意OGNL中{}代表的是集合

所以可以表达成:

第一个:age==1的集合

第二个:age>1的集合中的第一个元素的age的集合,因为就一个元素,所以后面的那个age集合也就是一个

3个:age>1的最后的那个集合的age属性的集合

4个:age>1的最后的那个集合的age属性的集合是否存在

OGNL访问整个value stack

之前的访问都是在value stack中的action对象

注意:一个value stack中,不是只有一个action可以有其他的。

上图是一个value stack,有一个aciotn和一个defaultTextProvider2个对象,

用:

调用action

按照常理:

[0]应该是访问value stack里面的第一个值,从上往下,就是OGNLAction

[1]:应该是访问 value stack 里面的第2个值,就是DefaultTextProvider

但是:[0]却是代表这整个value stack 中的对象,这样是为了避免有多个actionvalue stack中,找不到对应的值

除了[0],之外特殊,其他都是正常的.[1]就代表从上往下第2个对象。

通用标签

<s:property></s:property>标签

1.在标签中,只要是默认的对象是object 的 那么就会将字符串解析成为ognl表达式,那么就去value stack里面取值:

2<s:property value=这里的默认是object></s:property>,所以会将里面的字符串作为取值的key,然后输出。

3.如果要直接写出你给的字符串,则要字符串,所以要包2才可以。

4Default是没有value的时候,输出default的值。

5<s:property value=XX></s:property>,默认escapetrue,就是直接不解析<html>代码,碰到直接输出,没有html的效果。

<s:set></s:set>

value  type=string 是错误的,也是object,会将字符串解析成为ognl表达式。

id name 已经作废:var代替它们。

注意:有var就代表这个变量已经放入了action Context之中,用#来取得

set标签的作用:

将值 放到 各个 范围之中

默认放到action中,就是request 和 actionContext之中。

说明:

取值例子:

其中name的几个设置是旧的写法。不用理会。

<s:bean></s:bean>

name设置类详细信息

只有设置了var属性才能在在actionContext中找到,不然key是么有value

它会自动帮你new

<s:param >设置这个bean内属性的值

<include ></include>

由于有中文的时候会有问题,不用。

#$%

$用于struts.xml中,读取value stack 中的值

<s:fielderror></s:fielderror>

控制标签

if else

遍历集合

遍历map

注意:

定义map要在前面加#号,原因不详。

Keyvalue用冒号隔开

要取得一项做文章:

只要:

collection map array 或者实现了enumeration iterator接口,都可以用这个标签遍历

默认配置信息获取

Struts声明式异常处理

首先,我们要将所有的action调用的类的异常,都是向上抛出

就算是调用这个的action也是抛出(这里扩大异常的范围了)

然后在struts中配置:这个配置是针对某一个package的,不是全部的,

只要这个package范围出现错误就跳往那个页面error.jsp

针对全部的配置:

然后其他的从这里extend

(补全:extends = bbs2009_dafault

注意:全局的只写

并不把result写在这里,result还是写在每个各自的action下面。(这个是为了让异常更加详细,更有针对性,配置在全局里面也可以,不过记住,全局result要写在全局mapping上面!!)

【各自配置result的】运行过程:

首先会先在各自的自己的action中找mapping,有就找自己对应的result,然后输出jsp

如果没有,就从继承的里找mapping,找到后,再找自己actionrelsut后输出jsp

【全局result】运行过程 :自己推理:先全局mapping,有!-->自己reslut没有!-->全局relsut

default-action-ref 的问题

这个配置了以后,如果访问了这个namespace的非正常路径,都会转到default-action-ref所对应的action里面,注意:但是它不会去执行那个action对应的class

只会单单的去显示那个action所对应的result。如果正常访问路径就会执行class

解决方案

web.xml中配置action的名字:

就可以正常使用,即在访问路径错误的情况下,还能够执行class注意:后来发现,打XX的地方default-acton-ref还是需要的

I18N

调用资源文件的代码:

ResourceBundle rb = ResourceBundle.getBundle("test",Locale.US);

System.out.println(rb.getString("System.info"));

注意:Locale.US那里是写国家名,不是语言名字:不是:Locale.CHINESE

test是资源文件的前面部分名字:

资源文件后面的名字是固定的!

上一篇: web应用程序

下一篇: 技术架构

4000-880-989
(24小时热线)
联系客服
微信公众号

官方公众号

小程序

©2008-2022 CORPORATION ALL Rights Reserved. 昆明奥远科技有限公司版权所有 滇ICP备09003328号-1 滇公网安备 53011102000818号 增值电信业务经营许可证号:滇B2-20110045
昆明那家网络公司好,新媒体运营,网站优化,网络推广,网站建设,网页设计,网站设计,网站推广,云南网站公司,昆明新媒体公司,云南网红主播,昆明SEO公司,昆明网站建设,昆明网络推广,昆明网站优化,昆明网站推广,红河网站建设,大理网络公司,曲靖网络公司,丽江网站设计,昭通网络公司,保山大数据服务,智慧高速建设,智慧校园服务,云南IDC服务商,网络安全测评,等保测评,网站关键词排名优化服务,服务客户尽超2000余家,一切尽在奥远科技,服务电话:13888956730