struts笔记

编程技术  /  houtizong 发布于 3年前   82
Struts2的作用
1、action:
新建web project   java版本
设置 window server tomcat位置enable
     window prefernce   installed jdk版本
     软件包:struts-2.1.6   拷贝文件struts.xml  到src    
类库文件:lib下; 全考出了juni 与spring 考到lib下
naviget视图下可以看见所有的子文件夹
配置web.xml   filter的配置部分 url-pattern上写/*就可以了

2、练习hello.jsp
   修改struts.xml
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
        <action name="hello">
            <result>
                /Hello.jsp
            </result>
        </action>
    </package>
//修改原因:添加<constant name="struts.devMode" value="true" />
           配置常量 默认值为false 此时处于开发模式 便于随时修改内容立即出现反馈
修改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>

3、读取源码org.apache.struts2.dispatcher.ng.filter.jar
路径:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

设置方法:右击pre
代码提示设置

4、运行机制:
在客户端通过http向服务器进行请求,tomcat接收到请求,发现web.xml中的namespace
找到struts.xml,去找action中的results,然后访问到**.jsp,jsp文件将内容反馈给客户端




可以直接访问jsp,之所以绕一圈,经过一次中转,拿到最后的展现,是因为设计模式的可扩展性,虽然过程有些麻烦,但可以将请求和最后结果的视图分开,如果想换视图更方便灵活一些。直接在struts.xml中的result中更换一下视图名称就可以了。
5、namespace
Package作用:用来区分重名的情况
  Package name= ’front’ 前台的,namespace=‘/front’指定路径(可以不写,意味着 =“” ,意味着自己指定路径,只要找到有要找的jsp文件就处理action)  result (name=success 默认的一般不写)

访问jsp的效果---路径namespace=’’的好处

--------------------拷贝项目时做的修改:1、server上加载2、在项目的properites配置项里找下图中的context root 设置为新项目名称。

-------------------------引入项目时步骤:
1、

2、




-----------------------------要直接在jsp中写中文,进行以下设置





6、action
Struts1与struts2的区别在于:struts1的action与具体的struts环境绑定,离不开serve的环境也有要求
struts2 普通java类,直接写个小测试文件,测试它的方法就可以
Struts1 每次访问action只创建一次对象,用的同一个(启动时创建)将出现线程同步的问题
struts2每次访问action重新创建一个对象,解决了线程同步控制的问题,但是占用内存

过程:java类中有execute()方法返回的是string类型就可以访问
Struts2通过struts.xml文件找到action读取class文件时会创建一个新的messge对象,
调用它的execute()方法返回一个success,去找对应的jsp,将视图(jsp的内容)返回到客户端
所以
<result name="success">默认name=”success”
调用它的execute()方法返回一个success,有三种方法,开发中只用第三中(在src中创建一个class文件)

方法一:实现接口无法调用方法
public class IndexAction1 {
public String execute() {
return "success";
}
}
方法二:实现action接口,只定义了一个方法"success"可写为常量
import com.opensymphony.xwork2.Action;

public class IndexAction2 implements Action {
@Override
public String execute() {
return "success";
}
}
方法三:使用继承,方法重写影响不大,ActionSupport封装了很多方法,可以直接用
import com.opensymphony.xwork2.ActionSupport;

public class IndexAction3 extends ActionSupport {

@Override
public String execute() {
return "success";
}
}
Struts.xml的配置:class的路径
        <!-- Add packages here -->
  <constant name="struts.devMode" value="true" />
    <package name="main" extends="struts-default" namespace="">
        <action name="index" class="com.bjsxt.struts2.front.action.IndexAction3">
            <result name="success">/Action.jsp</result>
        </action>
    </package>
7、路径问题的说明
直接访问根路径:先到web.xml到对应的filter到对应的namespace(/)
如果没有找到则交给tomcat处理,根据welcom所以处理index.Jsp文件
struts2中的路径问题是根据action的路径而不是jsp路径来确定,所以尽量不要使用相对路径。
index.jsp
虽然可以用redirect方式解决,但redirect方式并非必要。
解决办法非常简单,统一使用绝对路径。
方法一:在jsp中用request.getContextRoot方式来拿到webapp的路径)





方法二:使用myeclipse经常用的,指定basePath(在head中添加标签
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>)


7、action的method     
Action执行的时候并不一定要执行execute方法<br />
可以在配置文件中配置Action的时候用method=来指定执行哪个方法

也可以在url地址中动态指定(动态方法调用DMI)(推荐)<br />
<a href="useradd">添加用户</a>
<br />
<a href="user!add">添加用户</a>
<br />
前者会产生太多的action,所以不推荐使用










8、通配符设置配置:
通配符一:*代表medthod中的方法名称,根据我们所传值往里面填充,

Index.jsp
<a href="Studentadd">添加学生</a>      //*=add
<a href="Studentdelete">删除学生</a>
StudentAction.java
package com.bjsxt.struts2.action;
import com.opensymphony.xwork2.ActionSupport;

public class StudentAction extends ActionSupport {
public String add() {
return SUCCESS;
}
public String delete() {
return SUCCESS;
}
public String update(){
return SUCCESS;
}
}
所以Jsp的命名规则需要一致
通配符二:约定大于配置
第一个 * = {1}  第二个 *= {2}   {2}是什么调用class里面的什么方法


<a href="Teacher_add">添加老师</a>
<a href="Teacher_delete">删除老师</a>
<a href="Course_add">添加课程</a>
<a href="Course_delete">删除课程</a>
<a href="Student_delete">删除学生</a>


在struts中有先后顺序问题,优先执行前面的,
所以挡在下面使用<a href="Student_delete">删除学生</a>时无法链接,出现下面的问题,
解决方法,将action的前后位置调换





9、传递参数,action接收参数,三种方式
可能的问题有
1) 有的问题为jdk的版本问题—jdk6   java compiler也设置为1.6(编译器兼容级别)
1.5实现的是接口,不能写@Override, 1.6可以
2) Tomcat 中设置的jdk版本

方法一:Action属性接收参数的链接,url里面传递的参数可以和成员变量一一对应,将url中的值传给
成员变量,参数值必须和方法名一致,当然也可以,但与约定不符,所以是一致的




<a href="user!add?name=a&age=8">添加用户</a>



也可以在url中给参数赋值,运行tomcat得到如下结果








方法二:Action DomainModel域模型=实体模块 接收参数,在问题域中存在的实体概念,


在add方法中直接调用的是另一个包中的对象,该对象存放的为属性,如下:




与第一种方法相比url中相当于直接调用其set方法,进行设置




当域模型中无某一项属性时,此时无法使用域模型,
解决方法一:属性接收
解决方法二:vo(值对象) do(数据对象) dto (数据传输对象,当参数传递过来与域模型匹配不上时使用,进行接收和传递参数)
Dto.java
package com.bjsxt.struts2.parameters.action.dto;

public class UserDTO {
private String name;
private String password;
private String confirmingPassword;//密码的确认
}
将DTO创建一个newuserDTO交到域模型中,



方法三:modelDriven模型驱动----》mvc   m(model,处理请求)  v视图(动态定义)c(控制器,action,控制它去哪请求,返回什么样的视图) 
实现ModelDriven 接口 ,只有一个方法getModel(),必须自己创建对象





过程:
Struts2接收到参数,new一个action,发现它实现了一个ModelDriven接口,
然后去调用ModelDriven的getModel()方法,拿到user对象
使用里面的方法,例如:setName()






10、中文问题-------web 界面出现乱码问题
Jsp文件:


Java文件

Struts文件:

效果:


Contant的配置:在 下面

<constant name="struts.i18n.encoding" value="GBK" /> <!-- internationalization -->
则将处理解决乱码问题



如果出不来则struts2.1.7中才可以,1.6中没有此方法啊,则将fielter进行配置
<!--<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>-->
或者设为:org.apache.struts2.dispatcher.filterDispatcher




11、简单的数据校验---手写校验
读源码方式:一条线分析:页面-提交-链接-后台如何处理
           业务逻辑:从一个页面一直读到它的数据库
     this.addFieldError("属性名", 具体校验信息");
error页面的标签<%@taglib uri="/struts-tags" prefix="s" %>
<s:fielderror fieldName="name" theme="simple"/>
Fielderror的作用,根据fieldName指定的属性名称,将存放在userAction里面的addFieldError的内容取出来 theme可以不写,将错误信息进行展现修饰css
标签位置:

D: \学习
\EclipseWorkSpase\Struts_project_wll\WebContent\WEB-INF\lib\struts2-core-2.3.7.jar\META-INF\struts-tags.tld
Error.jsp
<s:fielderror fieldName="name" theme="simple"/>
<br />
<s:property value="errors.name[0]"/>
<s:debug></s:debug>
加上标签信息验证后,错误页面无法链接,web页面出现Struts Problem Report
Tomcat中出现:
Could not find property [struts.valueStack]
原因:1、property无法取到debug中的值,将<s:property value="errors.name[1]"/>删除


<s:property value="errors.name[0]"/>取得为Value Stack Contents中的值
errors取出的为map,errors.name[]取出的为map的值



12、有人登陆,一般在登陆后在session中添加个值,确定登陆
后台拿不到session application request的值,所以通信有些困难,为了在action中访问到session application request ,进行下面的部署,response不用反馈
所以提供一种机制访问web元素

<input type="button" value="submit1" onclick="javascript:document.f.action='login1';document.f.submit();" />
document.f===form     action name== login1
action用javascript动态指定,document.f.submit()进行提交,这样就可以用多种按钮提交同一个form


     取得Map类型request,session,application,真实类型 HttpServletRequest, HttpSession, ServletContext的引用:
<ol>

<li>前三者:依赖于容器</li>
<li>前三者:IOC</li> (只用这种)
<li>后三者:依赖于容器</li>
<li>后三者:IOC</li>
方法一:

拿出request然后使用

private Map request;
private Map session;
private Map application;

public LoginAction1() {
request = (Map)ActionContext.getContext().get("request");
session = ActionContext.getContext().getSession();
application = ActionContext.getContext().getApplication();
}

定义map类型的request,
给它取值:request = (Map)ActionContext.getContext().get("request");
get("request")取得名为request的里面的值,取出的值是一个map
getContext(),*context *当前程序执行的环境内容,
eg:ActionContext,运行的周边环境,配置。。。
ActionContext.getContext()是否是单例?-----不是单例,里面是个stracklocal的对象
           
  往三个map中添加值看前台是否可以访问得到
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");

过程解析:在前台form中的submit提交了三组值(name,password),交给loginaction.Class来处理,
Loginaction通过定义三个属性,调用Context()将其设置好,通过put为其设置值,回到前台,用
httpRequest访问可以提取到put设置的值,struts2在处理
工程中将map中的值复制到httprequest中
使用标签形式访问request中的值
<s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />
Stak context

方法二:使用泛型实现三个接口
直接使用
       request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
这是一种设计思想//DI dependency injection 依赖注入(成员变量依赖struts2容器给自己注入一个值,才能使用)
        //IoC inverse of control 控制反转(控制权转手—交给容器,原本可以类自己控制request的值,现在交给容器来控制)

请求使Struts2找到对应的action,确定实现了requestAware接口,然后调用里面的setRequest(map)
方法,将map request交给action,然后存储使用,


这种方式经常使用IOC(或者说只用这种方式)
public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware, ApplicationAware {

private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;//泛型

//DI dependency injection
//IoC inverse of control
public String execute() {
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return SUCCESS;
}

@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}

@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}

@Override
public void setApplication(Map<String, Object> application) {
this.application = application;
}


}
方法三:固定写法,将private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
进行设置直接使用get*方法
方法四:
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;

public String execute() {
request.setAttribute("r1", "r1");
session.setAttribute("s1", "s1");
    直接进行set


拿web元素的方式分两种:map类型  真实类型,我们只用控制反转IOC



13 、struts.xml中的配置:
<include file=”login.xml”/>

将login.xml包含在struts中,
Login中写个人的配置,struts中公共配置

14、最后一个小程序
DefultAction
默认action的访问,访问时,当action找不到时就调用默认的action
网页不存在时,可以交给defultaction来处理,让它跳会主页
<defult-action-ref name=’index’></ defult-action-ref >





action总结:
1、 实现action的方法 继承ActionSupport
2、 Dmi动态方法调用     action的name!method的name
3、 通配符的使用:*_*  *{1}{2}
4、 接收参数的方法domainModel或者属性来接收
5、 参数验证:addfieldError、addactionerror 一般不适用struts中的UI标签
6、 访问web标签map类型用ioc或者依赖struts2
7、 包含文件的配置include
8、 默认action的配置defult-action-ref








Result
1、 result type:

服务器段跳转
客户端发送一个请求,访问url,forward在服务器上直接跳到下一个页面,在服务器将试图反馈给客户端
所以浏览器器上的结果页面的url:http://localhost:8088/Struts_project_wll/r/r1
客户端 服务器

客户端跳转
客户端发送一个请求,到url地址,redirect到一个地址 ,反馈给浏览器器,浏览器重新发送一个请求
给服务器,,服务器再将结果视图传给客户端
所以结果页面的地址为:http://localhost:8088/Struts_project_wll/Result-type/r2.jsp





2、 公用的结果集global-results
同一个package,使用公共的结果集
  <package name="user" namespace="/user" extends="struts-default">
<global-results>
    <result name="mainpage">/Result-Global/main.jsp</result>
    </global-results>

Class文件:get set方法定义一个type,下面使用
public String execute() throws Exception {
if (type == 1)
return "success";
else if (type == 2)
return "error";
else
return "mainpage";
}
Jsp页面:
<a href="user/user?type=1">
struts-default指的是:一种jar包内默认的配置,直接使用就可以
不同的package,使用上一个package的所有内容,则设置extends="user"
<package name="admin" namespace="/admin" extends="user">


3、 动态结果集:struts中 <result>${r}</result>
   Class文件中指定:定义两个成员变量type和r(get set 方法)
public String execute() throws Exception {
if(type == 1) r="/Result-Global/user_success.jsp";
else if (type == 2) r="/Result-Global/user_error.jsp";
return "success";
}//在class中动态指定跳转界面
4、 给result传递参数
服务器端的Forward 时不需要传递参数,因为此时action共享一个值栈,
一次request只有一个值栈,
传参数的情况:
Request在客户端跳转,发起新请求给另一个action,再次来一个request,出现了第二个值栈
因此此时,需要传递参数




Result总结
1、 常用的四种类型
Dispatcher(默认)
Redirect
Chain
Redirectaction
2、 全局结果集:
Global-results 不同的package想要使用它则进行extend
3、 动态结果集
在action中存储一个属性<result>${r}</result>,在class中给该属性动态传值
r="/Result-Global/user_success.jsp";
4、 传递参数
服务器端的forward不需要传参数,客户端的forward才需要传递参数
${ }不是EL表达式,而是OGNL中的
5、标签分类:generic tag  / ui tags(展现相关) form tags
规划小项目bbs(添加删除板块、界面原型、设计数据库、确定架构(struts)、到底用什么样的约定、配置文件、命名格式)
学习方式:重要的练习,不重要的有印象就可以了
学习技术的方法---忘记了就去查,数据结构设计模式等去深入学习

Ognl
一、 什么是ognl,有什么作用object graph navigation language 对象图导航语言

OGNL是Struts 2框架的默认表达式语言,增强了Struts 2的数据访问能力,同时简化了代码。
二、 一边加一边调试,先做原型,不断添加东西,添点调试点
三、Ognl使用
1、访问action普通属性: <s:property value=”username”>
Value后面的值为ognl表达式,s:property为标签
2、Value=”User.age”传递参数时在浏览器中必须以user.Age=**,才会构造,值栈中才有值,否则为空
如果在访问action时,直接new一个user对象,它就直接初始化,在值栈中就可以取到值,如果将user()方法去掉,在浏览器上传值,值栈中无法传值,此时值栈中值为null,后台Tomcat 报错,初始化出错,因此domainmodel必须设置一个参数为空的构造方法

3、普通对象的普通方法用:   .  调用
4、action的普通方法:直接调用方法eg:value=“add()”
5、访问静态方法:访问不到的原因2.1 的设置问题,需设置constant(在default.properties中)
<constent name =”struts.dgnl.allowStaticMethodAccess=true”>
Value=“@com.bjsxt.struts2.ognl.S@s()”S类名 @ s()静态方法名
6、访问静态属性:Value=“@com.bjsxt.struts2.ognl.S@STR”
S类名 @ STR静态属性名
7、只能访问该类 @@+类名 +方法(2,3)

8、访问普通类的构造方法:
<s:property value="new com.bjsxt.struts2.ognl.User(8)"/>

9、访问List:<s:property value="users"/>
10、访问List中某个元素:<s:property value="users[1]"/>
11、访问List中元素某个属性的集合: {}代表一个集合
<s:property value="users.{age}"/>
12、访问List中元素某个属性的集合中的特定值:
<s:property value="users.{age}[0]"/> |不采用该方法
常用这种写法:<s:property value="users[0].age"/>
13、访问Set:<s:property value="dogs"/>
14、访问Set中某个元素:<s:property value="dogs[1]"/>
Set无序,用此方式(通过下标来访问)是取不到值得
15、访问Map:<s:property value="dogMap"/>
16、访问Map中某个元素: dog101----map中的键
<s:property value="dogMap.dog101"/> |
<s:property value="dogMap['dog101']"/> |
<s:property value="dogMap[\"dog101\"]"/>
17、访问Map中所有的key:<s:property value="dogMap.keys"/>
18、访问Map中所有的value:<s:property value="dogMap.values"/>
19、访问容器的大小:<s:property value="dogMap.size()"/> |
<s:property value="users.size"/>
            再ognl中默认size为一种属性

20、投影(过滤):将符合条件的过滤出来
只有三种:?# ^
This 循环过程中的当前对象,在所有对象中中
直接拿出age=**的users对象
<s:property value="users.{?#this.age==1}[0]"/>
21、投影:<s:property value="users.{^#this.age>1}.{age}"/></li>
大于1的集合元素中的第一个  的age集的集合
22、投影:<s:property value="users.{$#this.age>1}.{age}"/></li>
大于1的集合元素中的最后一个  的age集的集合

23、投影:<s:property value="users.{$#this.age>1}.{age} == null"/>
               该集合是否为空
          24、[]:访问元素,内容,ognl对象的栈中从上往下数的第几个元素的集合
[0]代表action的位置
<s:property value="[0] "/>

访问成员变量[0].username
当值栈中有两个action的情况(不同的action,不同的result type)





               标签

一、 标签分类:generic tag  / ui tags(展现相关) form tags
二、 重要的标签




1、 Property
 Value---(ognl表达式或者字符串)
value属性默认为object类型可以将字符串解析为ognl表达式
Eg:<s:property value=”username”/>取值为ognl表达式
    <s:property value=”’username’”/>取值为字符串
 Default设定
Eg:<s:property value=”admin” default=”管理员”>
    当value值取不到时,将使用默认值default
 Html设定
Eg: <s:property value=”’<hr/>’” escape=”false”/>
     Escape 为true时,返回的是一个字符串<hr/>
     Escape 为false时,返回的是html效果一条直线
2、Set    jsp做视图时不用,修改变量的名称时可以用到
 Id name 已经废弃
 Var   定义一个变量
     两种情况:一、指定scope 
               二、未指定scope(默认范围为request和actioncontext)
 Scope指定范围
3、 Bean
 id 废弃
 name
string类型---bean的对象
 var 要不要将bean new的对象放入context中
开始创建对象,并将该对象放在栈顶,bean结束将其拿走要想在context中找到设置的值
需将name与var一起使用

eg:<s:bean name="com.bjsxt.struts2.tags.Dog"  >
<s:param name="name" value="'pp'"></s:param>
<s:property value="name"/> ‘name= Dog的name’
             <s:debug></s:debug>//若不设置var则将debug放在bean中间
</s:bean>
           若想bean结束还要访问里面的内容,则进行以下设置
              <s:bean name="com.bjsxt.struts2.tags.Dog" var="myDog">
<s:param name="name" value="'oudy'"></s:param>
</s:bean>
拿出值:
<s:property value="#myDog.name"/>

       4、include   包含文件一般不适用
              一般使用Jsp中的包含有两种<%@include> 静态包含 或者jsp:include

 value ---默认类型字符串
include _include1.html 包含静态英文文件包含静态中文文件
<s:include value="/_include1.html"></s:include>
include _include1.html 包含静态英文文件,说明%用法
<s:set var="incPage" value="%{'/_include1.html'}" />
<s:include value="%{#incPage}">
</s:include>


$用于i8n和strut配置文件
#取得actiontext中的值
%将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用
         
5、 fielderror    class中加addfielderror("fielderror.test",worry )
theme 默认simple xhtml   css_xhtml ajax
<s:fielderror fieldName="fielderror.test" theme="simple">
</s:fielderror>
6、 if elseif else
  age必须取精确的值
age = <s:property value="#parameters.age[0]" /> <br />

<s:set var="age" value="#parameters.age[0]" />//方便下面引用

Eg:<s:if test="#age < 0">wrong age!</s:if>

<s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>

<s:else>yeah!</s:else><br />
<s:if test="#parameters.aaa == null">null</s:if>
7、 iterator  遍历 遍历任何集合及数组
 遍历集合<s:iterator value="{1, 2, 3}" >
    <s:property/> |//将集合中的元素取出来
</s:iterator>
 将集合的值拿出来放到x中,用#x.toUpperCase()取出来(字符串)
<s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
<s:property value="#x.toUpperCase()"/> |
</s:iterator>
 Status  --- 状态,循环到现在的当前的状态
<s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
<s:property/> |
遍历过的元素总数:<s:property value="#status.count"/> | //索引
遍历过的元素索引:<s:property value="#status.index"/> |
当前是偶数?:<s:property value="#status.even"/> |
当前是奇数?:<s:property value="#status.odd"/> |
是第一个元素吗?:<s:property value="#status.first"/> |
是最后一个元素吗?:<s:property value="#status.last"/>
<br />
</s:iterator>
 遍历Map   必须加#
方式一:
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" >
<s:property value="key"/> | <s:property value="value"/>
<br />
</s:iterator>
方式二:
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/>
  <br />
</s:iterator>
8、 Subset
9、 Push
10、 UI标签----theme(主题)
有四种主题:simple xthml css_html ajax
默认主题:xhtml
不同主题产生的效果查看源码
推荐用法:自己定义自己的主题
但快的方法就是使用css,进行修改覆盖原主题
只有filederror需要进行修改,其他的使用simple就可以
1、 覆盖原来的css,需要看源码
2、 覆盖单个文件
3、 定义自己的theme
4、 实战:
把所有主题定义为simple
Fielderror特殊处理
自己控制其他标签的展现
     
                                                                                                                              
小项目的命名约定
原则:简单就是美
Strut2命名规则---网上查找
1、 表命名:_BiaomingItem
2、 字段命名:保持和属性名一致,尽量不要起名和数据库中的命名冲突
3、 库名:项目名称
4、 用层来划分包 com.bjsxt.bbs.action model(bean) service dto(vo)
5、 Action ****Action
6、 配置 *-*(建议使用中划线)
7、 Namespace   /admin    界面原型的名称
     项目开发顺序
1、 建立界面原型
2、 建立struts.xml
a) 确定namespace
b) 确定package
c) 确定action的名称
d) 确定result
e) 将界面原型页面进行修改,匹配现有设置
f) 测试
3、 建立数据库
4、 建立model层
5、 建立server层
6、 着手开发




声明式异常处理
1. 在Actoin中进行异常映射
2. 在package中进行全局异常映射
3. 使用继承共用异常映射
4. Struts2中异常处理由拦截器实现(观察struts-default.xml)
a) 实际上Struts2的大多数功能都由拦截器实现(拦截器————在struts调用action过程中添加一些个人的逻辑)
I18N
1. I18N原理
a) ResourceBundle和Locale的概念
b) 资源文件
c) native2ascii
2. Struts的资源文件
a) Action – Package – App级
b) 一般只用APP
i. struts.xml custom.i18n
c) PropertiesEditor插件
i. 解压
ii. features plugin 覆盖到myeclipse中的eclipse目录里
d) 动态语言切换
i. request_locale=en_US
3、代码国际化:
   
4、Struts2中的国际化:
   国际化资源文件:
   英文:**_en_US.properties
    login.username=username:
login.password=password:
login.login=login
welcome.msg=welcome:{0}
   汉语:**_zh_CN.properties
     login.username=用户名:
login.password=密  码:
login.login=登录
welcome.msg=欢迎你:{0}
jsp设置方式
<s:property value="getText('login.username')"/>
动态切换语言:
  Action:
         <action name="lang" class="com.bjsxt.bbs2009.action.LangAction">
       <result>/admin/Login-input.jsp</result>
         </action>
Jsp:
         <a href="admin/lang?request_locale=en_US">en</a>


Struts拦截器以及源码解析
1. Struts架构图
Struts执行过程分析
Struts2filter调用serrviceAction()接着调用dispatcherserviceaction在这里创建了actionproxy,在actionProxy里有actionInvocation调用它的invoke(0,actioninvocation依次调用intercept(0,最后调用testaction的excute().

2. Interceptor拦截器过程模拟
3. 定义自己的拦截器implements Interceptor
Java文件:
  public class MyInterceptor implements Interceptor {
public void destroy() {}
public void init() {}
public String intercept(ActionInvocation invocation) throws Exception {
long start = System.currentTimeMillis();
String r = invocation.invoke();
long end = System.currentTimeMillis();
System.out.println("action time = " + (end - start));
return r;
}
a) acegi – spring security
<interceptors>
<interceptor name="my" class="com.bjsxt.interceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="test" class="com.bjsxt.action.TestAction">
<result>/test.jsp</result>
<interceptor-ref name="my"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
4. 使用token拦截器控制重复提交(很少用)
  
   <result>/addOK.jsp</result>
   <interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="token"></interceptor-ref>
<result name="invalid.token">/error.jsp</result>

类型转换
a) 默认转换
i. 日期处理<s:date name="d" format="yyyy/MM/dd HH:mm:ss"/><br/>
b) 写自己的转换器:
public class MyPointConverter extends DefaultTypeConverter{

@Override
public Object convertValue(Object value, Class toType) {
if(toType == Point.class) {
Point p = new Point();
String[] strs = (String[])value;
String[] xy = strs[0].split(",");
p.x = Integer.parseInt(xy[0]);
p.y = Integer.parseInt(xy[1]);
return p;
}
if(toType == String.class) {
return value.toString();
}
return super.convertValue(value, toType);
}

}
public class MyPointConverter extends StrutsTypeConverter{



@Override
public Object convertFromString(Map context, String[] values, Class toClass) {

Point p = new Point();
String[] strs = (String[])values;
String[] xy = strs[0].split(",");
p.x = Integer.parseInt(xy[0]);
p.y = Integer.parseInt(xy[1]);
return p;


}

@Override
public String convertToString(Map context, Object o) {
// TODO Auto-generated method stub
return o.toString();
}

}

c) 三种注册方式:
i. 局部:XXXAction-conversion.properties
1. p(属性名称) = converter
ii. 全局:xwork-conversion.properties
1. com.xxx.XXX(类名)= converter
iii. Annotation
d) 如果遇到非常麻烦的映射转换
i. request.setAttribute();
ii. session

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客