----------------------------------------struct2---------------------------------------------------
1 . 什么是struct2 ?
面向程序员的java程序框架
struts = jsp + servlet
1.获得客户端参数
2.数据类型转换
3.数据格式验证
4.将参数包装成一个pojo类型
5.将需要显示的数据传递给jsp
6.将请求放给jsp
7.jsp显示servlet传递过来的数据
2. 为什么要学习struct2 ?
提高代码复用,又快又好的提高web应用.
快: 提供大量基础模块,加快web开发
好: 应用了MVC 在内的好多的设计模式,提高代码的维护性
3. MVC 及struct的流程;
基础模块的使用;
1.表单验证;
2.文件上传(文件拷贝);
3.国际化(不同的语言版本);
4. 什么是MVC?
定义: web应用开发框架
组成:
1.控制器(Controller)
1.接收客户端请求
2.根据请求调用相应的模型层方法
3.选择一个视图层进行响应
2.模型层(Model)
1.封装应用的状态信息
2.提供方法处理状态信息的方法
3.重新将状态信息显示到视图层
3.视图层(view)
1.用户根系统交互的接口
2.发送请求给控制器
3.接收模型层的通知重新显示数据
流程:(web应用里的MVC)
view<---->Controller<----->Model<---->持久层<---->DB
M :javaBean(封装数据,封装数据访问逻辑) sessionBean
---------------------------------------------------------
V: html ,xml , jsp
---------------------------------------------------------
C: servlet , struts1: actionForm,actions
struts2: FilterDispatcher Actions
注意:
dao 模式中的service , Dao ,action 层 主要属于 Model层
jsp ,html 页面等属于 View层
servlet ,或者struts中的 FilterDispatcher属于Controll层
层:考虑软件的维护性 |
| 软件 公司
原始的两层结构: | 功能 职责
1. 交互层 | 层 部门
2. 处理层 | 表现层(view) (jap,html) 市场部
| ( 1.接受请求
| 2.呈现结果)
|
| 控制层(controller) (servlet) 管理部
Mapping
(将请求发给合适的模型层)
(将响应发给相应的表现层)
|
| 模型层(Model) (javaBean) 生产部
| 处理请求,业务逻辑
|
持久层(dao模式) (jdbc,hibernate)
实现数据的crud 仓管
| 数据库 (dao) 仓库
|
5.MVC的种类:
模式一; (jsp作为控制)
模式二: (servlet作为控制)
区别:控制实现的技术
6. MVC模式2 中的servlet的数量:
方式:(一般用第三种)
1. 一个servlet
2. 一个rvlet
3. 一个总体流程控制的serv请求一个selet,多个具体流程控制的servlet
7.MVC提供的功能:
1.自动获得客户端提交的参数
2.自动进行数据类型转换和数据格式验证
3.自动进行数据的包装
4.能够更方便的将显示的数据传递给视图
5.自动进行请求的转发
6.提供标签库,能够更方便的构建视图
7.国际化的实现
8.能够更方便的跟其他框架进行集成
------第二章--------
1. 什么是struct ?
最早的mvc开源框架
DAO模式:(data access object) 数据访问对象
分类:
1. data access
使用接口,降低持久层和持久调用层的耦合性
Icustomer.java 持久调用层关注
具体的接口实现完全有自己实现
2.active domain object
customer.java
使用JavaBean封装和传递数据
JavaBean的特点:
1.属性
作用:用来持有数据
2.所有属性设置get,set方法
好处:简化访问
3.建议使用无参的构造器
作用:简化实例化
4.实现java.io.Serializable接口
作用:序列化;
|------------------------Dao模式-------------------------------|
view<---->Controller<----->Model<--接口交互-->持久层(实现接口,实现不同的技术应用)<-接口交互--->DB
2.struct2对MVC各层的贡献:
1. View
struts框架标签
2.Controller
1.FilterDispatcher(总体流程控制) ---变形前---->servlet
类型:Filter
作用:总体流程控制
提供:有框架提供
2. Action(子流程控制) ---变形前----->servlet
类型:普通java类
作用:具体流程控制
提供:由程序员提供
3.配置文件 struct.xml
内容:那个请求,由哪个Action处理,跳转至那个页面显示
4.拦截器:
作用:提供基础模块,一个拦截器一个模块
3.Model
没贡献
3.struct2.的流程时序:
1.用户发出请求;
http://localhost:8080/struct2/login.action
http://localhost:8080/struct2/register.action
/struct2 :request.getContextPath();
/struct2 :request.getServletPath();
2.FilterDispatcher处理请求;
读取struct.xml,判断请求对应的Action是否存在
-----------------
web.xml
<filter-mapping>
<filter-name></filter-name>
<filter-pattern>*.action</filter-pattern>
<filter-mapping>
/ :代表服务器根路径:
1.<form action="/a.action">
2. response.sendRedirect("a.jsp");
3.拦截器处理请求()
提供基础功能:
将请求参数传递给Action对象属性;
文件上传;
4.Action处理请求
调用模型层处理请求
register.jsp
RegisterAction.java
src/struts.xml
view<---->Controller<----->Model<---->持久层<---->DB
5.相应结果资源执行
6.拦截器处理结果
7.浏览器显示结果
-----------regist.jsp----------
Customer Register
-----------------
name:[ ]
password:[ ]
address:
tel:
register reset
-----------------------------
xml文件:
良构性
有效性:DTD schema
-----------------tomcat 5.0 与struct2及jdk解析问题---------------------------------------------------
配置:
----------tomcat安装路径/common/endorsed/覆盖所有-------------------
----------------------------------------------------------
4.作用域:
request
session setAttribute(String s,Object o);
Object getAttribute(String s,Object o);
Servletcontext
5.struts中个组件的功能:
1.控制层:
类别:
1.ActionServlet(公司老总)
由框架提供的一个类,接收客户端的所有请求,但是本身不会处理请求,
而是将请求委托给requestProcessor全权处理
2.requestProcessor(项目经理)
struts提供的一个类,用来接收actionServlet 转发过来的请求
3.Action:(程序员)
框架提供的一个类,功能与Servlet一样作为控制器来控制和转发请求,
并且由他开调用model 模块中相应的方法,完成相应的业务,并根据不同的结果
选择不同的jsp视图显示
注:我们程序员要做的就是要完成Action类
2.model层:
ActionForm:
由struts提供的一个类,作用:
1.封装提交表单中的字段信息
2.对提交表单中的字段信息进行验证(服务端验证)
3.可以对表单中的信息进行重新赋值
注意:1.我们用户也要定义一个类去继承actionForm
2.一个action可以配置一个actionForm,也可以不配置,
actionForm可以被多个action使用
6.struts的环境搭建:
1.构建web工程导入struts jar包
2.在web.xml中配置主控器:(FilterDispatch)
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.在src目录下创建struts.xml,(struts.property.log4j.property文件)
7.使用struts的基本步骤:
1.创建jsp月面.提供用户输入表单页面,注意下action属性的配置
2.创建相应的action类.
1.提供属性用来存放提交的信息,
2.设置get/set方法,
3.提供execute()方法;
注意:property 的名字必须与客户端提交的参数名字相同
3.在struts.xml中配置action,包括名字和类型,并提供action返回的字符串
以让中控器来控制跳转页面,显示
<action name="ct" class="web.action.ConverterAction">
<result name="success" >/co.jsp</result>
</action>
注意:<result name="success" >中的name必须与程序action中execute()
方法返回的字符串值相同;
目的:为了让主控器根据返回值控制跳转
---第三章---Action results----
1. Action
action类的实现方法:
1.普通的java类,不去实现任何方法,或接口
2.实现 action接口
优点:可以使用action接口中定义的常量
3.继承actionSupport类:
优点:可以再自定义的类中使用actionSupport中
定义的方法;
1.访问Servlet 中对象的方式:
1.使用ActionContext 辅助类(优先推荐使用)
2.实现接口:servletContextAware
servletRequestAware
servletResponseAware
3.使用ServletActionContext
//Action 访问servlet api
//方式一:(推荐方式)
ActionContext.getContext().getSession() //方法链条
.put("smsg", e.getMessage());
//方式二:
request.setAttribute("rmsg", "request:"+e.getMessage());
//方式三:
ServletActionContext.
getServletContext()
.setAttribute("amsg", "application:"+e.getMessage());
选择依据:
1. 对代码是否有侵入性
2. 是否引入新的api ,是否便于测试
2.action的配置:
一个Action处理多个请求
将多个请求代码写在一个Action的不同方法中
如何区别请求以调用合适的方法:
1. 提交请求时 通过 !方法名 形式制定调用方法
<form action="registCustomer.action!regist" method="post">
<action name="customer" class="web.action.CustomerAction">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
<result name="loginSuccess">/index.jsp</result>
<result name="loginErr">/login.jsp</result>
<result name="input">/register.jsp</result>
<interceptor-ref name="logger"/>
</action>
web.action.CustomerAction.java
2. 通过配置文件中的method属性指定调用的方法;
<action name="loginCustomer" class="web.action.CustomerAction" method="login">
<result name="loginSuccess">/index.jsp</result>
<result name="loginErr">/login.jsp</result>
</action>
<action name="registCustomer" class="web.action.CustomerAction" method="regist">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
</action>
3.通过通配符减少配置性新内容
<action name="*Customer" class="web.action.CustomerAction" method="{1}">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
<result name="loginSuccess">/index.jsp</result>
<result name="loginErr">/login.jsp</result>
</action>
namespace :action 寻找action的路径,默认为 / ,配置为:
<package name="jd0908" namesp="/a">
4.解决转向的action不存在的处理方法:
<default-action-ref name=""/>
2.results 响应资源的配置:
1. 局部result:放在单个action之间的result为局部result
<action name="registCustomer" class="web.action.CustomerAction" method="regist">
<result name="registSuccess">/login.jsp</result>
<result name="regisErr">/register.jsp</result>
</action>
全局result:
减少action中相同内容result的配置信息
<global-resultas>
<result name="registSuccess">/login.jsp</result>
<global-resultas>
使用的时候为就近原则
2. 跳转方式:
result type:
设置跳转类型或响应资源类型
1. redirect (客户端重定向)
http://localhost:8899/struct2/register.jsp
<result name="registSuccess" type="redirect">/login.jsp</result>
----->
http://localhost:8899/struct2/login.jsp
2. dispatcher(默认)
3.plainText
4.Chain类型的result type:(服务器内部跳转)
共享同一个请求方式,跳转至另一个action
input.jap chainA.jsp chainB.jsp
------------- --> ---------- --> ---------------
name=zs name+=chainA; name+=chainB;
name=zs -----> zs->chainB
name= -----> ->chainB
-----> null->chainA->chainB
1.有共同的参数和属性,优先选择参数值
3. 动态result:不知道跳转到何处,跳转位置由客户决定
将action属性值作为result路径或部分组成内容
获得属性值:${属性名}
<action name="baidu" class="web.action.BaiduAction">
<result name="success">${path}</result>
</action>
--- 第四章---Struts tag Library-------------------
1. struts标签分类:
1.non-UL (非用户界面标签)
1. (流程控制标签)
<s:iterator id="" value="map/list/set/array" status=""/>
id:如果指定了Id,迭代出来的数据除了放在值栈中外,还放在ActionContext中
status:存放当前数值的状态信息
<s:if test=""/>
当test中的值为真时执行本体中的内容
2. (date标签)
<s:property value=""/>
从值栈中取值
<s:set name="" value="" scope=""/>
将value表示的值设置到为name的作用于中;
<s:push value=""/>
将某个值放到值栈顶
具体的见<<J2EE笔记>>
2.ul(用户界面标签)
form 表单和非表单标签:
<body>
<center>
<h3><br></h3><h3>Customer Register</h3>
<s:form action="register" >
<s:textfield name="name" label="Name"/>
<s:password name="password" label="Password"/>
<s:checkboxlist name="hobby" label="Hobby"
list="#{'计算机':'computer','play':'playing','read':'reading'}"
listKey="value"
listValue="key"
value="{'reading'}"/> <!-- 预先选定的值 -->
<s:radio name="gender" label="Gender"
list="#{'男':'male','女':'remale'}"
listKey="value"
listValue="key"
value="'male'"/>
<s:datetimepicker name="date" label="birdDay"/>
<s:set name="date" value="#{
'上海市':{'闸北区','黄浦区','嘉定区'},
'山东省':{'潍坊市','济南市','枣庄市','威海市'},
'内蒙古':{'呼和浩特','呼伦贝尔','包头'}
}"/>
<s:doubleselect label="地址" name="address"
list="#date.keySet()"
doubleName="c"
doubleList="#date[top]"></s:doubleselect>
<s:textarea label="other" name="text" cols="10" rows="3"/>
<tr><td colspan="2" align="center">
<s:submit value="submit" align="center" theme="simple"/>
<s:reset value="reset" align="center" theme="simple"/>
</td></tr>
</s:form>
3.AJAX
注意:
在struts中如何将action交给jsp实现?
1.将数据放在在request范围内传递过去,然后jsp在从request范围取出,显示
2.将要传递的数据作为action的一个实例变量(action的引用会被struts框架 放置在值栈中) ,jsp再从值栈中获得
2 .ognl(对象图导航语言)
标记库组成:
1.标记库处理类
2.标记库描述文件
3.jsp中使用;
<%@taglib uri="" prifix=""%>
1.标记库描述路径;
2.标记库描述文件在web.xml中取的别名(使用路径的改变)
3.标记库描述文件中uri元素内容 (推荐使用)
访问实例:
<h2>ognl的使用</h2>
<h3>ognl表示的具体值</h3>
字符串:
<s:property value="'hello world'"/><br>
数值:
<s:property value="100"/><br>
Boolean:
<s:property value="false"/><br>
运算:
1+1=
<s:property value="1+1"/><br>
1>2?
<s:property value="1>2"/><br>
'a'.equals('b')?
<s:property value="'a'.equals('b')"/><br>
<h3>定义数组</h3>
{#request.s1,'hellow',23}
<h3>定义map</h3>
{'s1':#request.s1,'name':'hellow'}
<h3>访问各种作用域的对象</h3>
page:<br> #attr.属性名称(先从page中找.若没有则在request中找,没有在到其他的里面中依次)
request:<br> #request.属性名称
session:<br> #session.属性名称
application:<br> #application.属性名称
action:<br> #属性名称(attribute)
valueStatck:<br> 对象的属性名(property)
parameter: #parameters.属性名: 访问请求的参数
<h3>访问静态方法</h3>
<s:property value="@java.Math@random()"/> //生成一个随机数
<h3>获得参数</h3>
<s:property value="#parameters.n1[0]"/> //得到参数值形成的数组,再得到某个元素
访问actionContext中的数据:
<S:property value="#key"/>
----------第四章--格式转换和------------------
1. 内置类型转换器:
1.转换成特定的类型转换对象
1.jsp:
<input name="cust.name"/>
<input name="cust.password"/>
2.action:
private Customer cust;
3.result jsp:
<s:propertry value="cust.name"/>
2.转化成数组:
1.jsp:
<input type="checkbox" name="hobby>
<input type="checkbox" name="hobby>
2.action:
private String[] hobby;
3.转化成List:
1.jsp:
<input type="checkbox" name="hobby>
<input type="checkbox" name="hobby>
2.action:
private List<String> hobby;
4.转化成map:
1.jsp:
<input type="text" name="h.a>
<input type="text" name="h.b>
<input type="text" name="h.c>
2.action:
private Map<String,Strin> h;
2. 自定义的类型转换器:
1.编写一个类(类型转换处理类)
1.继承StrutsTypeConverter 类:
2.重写方法:
convertFromString(); 拦截器去调用
convertToString(); 拦截器去调用
例:
zs:123:shanghai:123456-------->Customer
String[] split(":");
2.通过配置文件,告诉框架类型转换器的存在
1.名称:
ActionName-conversion.properties
例: ConverterAction-conversion.properties
2.路径:
和Action 同目录
3.内容:
属性名称=类型转换器完整类名称
例: cust=web.converter.CustomerConverter
3.interceptor(拦截器)
1. 什么是拦截器?
struts中的Filter
1. 拦截器是struts框架中提供基础服务的一种组件,在Action运行前后执行
2. 当多个Action使用同一种功能时,可以将这个功能放在拦截器中
3.拦截器是可以重用的,当某个拦截器需要某种功能时,只要用拦截器去拦截这个Action
2.问什么要使用拦截器?
为了维护性,重用性
3.拦截器栈:多个拦截器
4.如果没有显示的让某个Action去使用某个拦截器,Action会使用框架提供的默认的拦截器
如果显示的调用了某个拦截器,必须在显示调用默认的拦截器
5. 拦截器的使用:
1.先写一个拦截器处理类,实现Interceptor接口
init(),destory() ,intercept();
主要实现intercept();
2.通过配置是用拦截器
1. <interceptors>
<interceptor name=" 名字" class="完整类名"/>
</interceptors>
注意:必须放在配置文件的最前面,否则出错
2. <action name=" " class=" ">
<result name="success" >/bidroutput.jsp</result>
<interceptor-ref name="名字"/>
<interceptor-ref name="defaultStack"/>
</action>
注意:要注意.要显示调用默认的拦截器,否则出错
6.内置的拦截器:
1.Params:
实现将请求提交的参数传递给action,
2.staticParams:
将action配置的参数值传递给action同名属性
<param name="className">jd0908</param> -----js0908-------> private String className;
3.Autoiring 与spring框架配合使用(不是默认的defaultStack)
4.FileUploads:
文件上传
注意:
1.在请求的即将结束的时候服务器会将上传的临时文件删除,同时复制一份保存在服务器端
2.客户端请求方式必须为post方式,
<s:form action="upload" enctype="multipart/form-data">
<s:file name="pic" label="File"></s:file>
<s:submit value="submit"></s:submit>
</s:form>
3.服务器端:
//制定好上传的临时文件
private File pic;
//制定上传的文件名
private String picFileName;
private void fileCopy() {
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
String path = ServletActionContext.getServletContext().getRealPath("/upload");
System.out.println(path);
in = new BufferedInputStream(new FileInputStream(pic));
out = new BufferedOutputStream(new FileOutputStream(path+"\\"+picFileName));
//判断文件是否读取完毕
int i = -1;
//用来存放读取到的字节内容
byte[] buffer = new byte[1024*8];
while((i=in.read(buffer))!=-1){
out.write(buffer,0,i);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(in!=null) in.close();
if(out!=null) out.close();
} catch (Exception e) {
}
}
5. validation
表单验证
--第四章---validation--表单验证--------------
1.什么是表单验证:
判断用户提交的参数是否正确:
1.该填的是否填写
2.格式是否正确
3.长度是否正确
2.为什么验证:
我们不能假设用户提交的数据是否都是正确的,避免服务器资源浪费或避免程序终止
3.种类:
1.客户端完成: -------->javaScript
尚未提交请求前,由浏览器先行完成
2.服务器端完成 : ------->java
流程: 客户端提交请求----->判断是否有错误------有---->inputaction
|
|---->没有---->其他执行
1.手动验证:
1. 必须继承ActionSupport
实际开发中我们继承 FieldValidatorSupport 类
2. 重写validate()方法
或者validateXXXX()方法;(例如:validateLogin();)
public void validateRegist(){
String name = cust.getName();
String pwd = cust.getPassword();
if(name==null||name.trim().length()==0){
addFieldError("name", "please input your name!!!!");
}
if(pwd==null||pwd.trim().length()==0){
addFieldError("pwd", "please input your password!!!!");
}
}
3.提供input名称的result
<result name="input">/register.jsp</result>
当出错时,系统自动调用input对应的action
4.使用标记显示错误信息
<s:fielderror/> ------>addFieldError();
<s:actionerror/> ------>addActionError();
姓名:<input type="text" name="cust.name"/>
<s:fielderror>
<s:param>name</s:param>
</s:fielderror>
<br>
密码:<input type="password" name="cust.password"/>
<s:fielderror>
<s:param>name</s:param>
</s:fielderror>
<br>
2.使用验证框架:
1. 必须继承ActionSupport
2.提供配置文件,告诉框架
1.那个名称的属性
2.进行什么类型的验证
3.出错提示信息
3.提供input名称的result
4.使用标记显示错误信息
注意:与手动的区别是第二步不同
手动:
为重写validate()方法
或者validateXXXX()方法;(例如:validateLogin();)
框架:
使用配置文件
当有多个验证,时为了节省资源不去验证下面的:
配置: short-circuit="true"
<field-validator type="stringlength" short-circuit="true">
<1> 怎么使用;
配置文件名称:
类名(action类名)-validation.xml
或: 类名(action类名)-aliasName-validation.xml
注:
类名(action类名) 必须为:对应的那个action类名
别名aliasName 必须为提交过来的那个action的类名
例:
registCust.action----->CustomerAction.java
.regist()
CustomerAction-registCust-validation.xml
路径:
与action同一目录
配置文件:
<validators>
<field name="cust.name" >
<field-validator type="requiredstring">
<message>Please Input Your Name......</message>
</field-validator>
</field>
<field name="cust.password" >
<field-validator type="requiredstring">
<message>Please Input Your Password......</message>
</field-validator>
</field>
</validators>
jsp配置:
<form action="registCustomer.action" method="post">
姓名:<input type="text" name="cust.name"/>
<s:fielderror>
<s:param>cust.name</s:param>
</s:fielderror>
<br>
<2> type 内置表单验证处理类
<field-validator type="requiredstring">
<validators>
<validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
</validators>
1.required:
当空时提交为 ""
2.requiredstring :
注:与required的区别为:
当空时提交为 null
<field-validator type="requiredstring">
<message>Please Input Your Name......</message>
</field-validator>
3.stringlength:
<field-validator type="stringlength">
<param name="minLength">6</param>
<param name="minLength">6</param>
<message>Please Input Your Name is 6 to 8 ......</message>
</field-validator>
4.int:
<3> 自己定义表单验证处理类:
1.实现接口 Validator或继承父类 FieldValidatorSupport
2.通过配置文件告诉框架该类的存在
位置:
classpath/validators.xml 即在src目录下
使用自己的验证类:
第一步: 创建类:
public class PrefixValidator extends FieldValidatorSupport{
private String prifix="021";
public void validate(Object arg0) throws ValidationException {
String fieldName = getFieldName();
String fieldValue = (String) getFieldValue(fieldName, arg0);
if(!fieldValue.startsWith(prifix)){
addFieldError(fieldName, "must start begin with "+prifix);
}
}
第二步: 设置配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
<validator name="prefix" class="web.validator.PrefixValidator"/>
</validators>
第三步:在使用的地方配置:(自定义的配置文件中 例:CustomerAction-registCust-validation.xml)
<field name="cust.password" >
<field-validator type="prefix">
<message>Please Input Your Password......</message>
</field-validator>
</field>
------第五章 国际化-------
1.
2.准备资源文件:
1.创建配置文件:
在某个目录下创建配置文件:
名为:
xxx.properties
xxx_字符编码.propertie
例:
laug.properties
laug_ch_CN.properties
注意:xxx_字符编码.propertie ,中字符编码必须问真实的不能为任意的编码名
2. struts.xml配置:
<constant name="struts.custom.i18n.resources" value="common.laug"/>
根据配置文件找到配置的语言文件
3.jsp中:
<s:password name="password" key="label.password"/>
struts2原理
发表回复