前几天不是一个同事使用OpenSessionInView pattern时,遇到Hibernate 3的mappinglazy="true"的问题,也不会想到它
struts启动spring的WebApplicationContext
spring有三种启动方式,使用ContextLoaderServlet,ContextLoaderListener和ContextLoaderPlugIn.
看一下ContextLoaderListener的源码,这是一个ServletContextListener
/**
* Initialize the root web application context.
*/
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
/**
* Create the ContextLoader to use. Can be overridden in subclasses.
* @return the new ContextLoader
*/
protected ContextLoader createContextLoader() {
return new ContextLoader();
}
contextLoader的源码
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
throws BeansException {
long startTime = System.currentTimeMillis();
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
servletContext.log("Loading Spring root WebApplicationContext");
try {
// Determine parent for root web application context, if any.
ApplicationContext parent = loadParentContext(servletContext);
WebApplicationContext wac = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
if (logger.isInfoEnabled()) {
logger.info("Using context class [" + wac.getClass().getName() +
"] for root WebApplicationContext");
}
if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext [" + wac +
"] as ServletContext attribute with name [" +
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}
return wac;
}
catch (RuntimeException ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
注意WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,这里面放了WebApplicationContext,需要使用时从ServletContext取出
可以使用WebApplicationContextUtils得到WebApplicationContext
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (attr == null) {
return null;
}
if (attr instanceof RuntimeException) {
throw (RuntimeException) attr;
}
if (attr instanceof Error) {
throw (Error) attr;
}
if (!(attr instanceof WebApplicationContext)) {
throw new IllegalStateException("Root context attribute is not of type WebApplicationContext: " + attr);
}
return (WebApplicationContext) attr;
}
关键的问题在于struts如何启动的spring的,ContextLoaderPlugIn的源码
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
public String getServletContextAttributeName() {
return SERVLET_CONTEXT_PREFIX + getModulePrefix();
}
不同加载的Key竟然不同,原因就是WebApplicationContext放在那里的问题,可spring调用的时候会根据WebApplicationContext里面定义的那个名字去找的,问题出在这里
在struts-config.xml中配置
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
<controller>
<set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor" />
</controller>
原理是这样的,Struts虽然只能有一个ActionServlet实例,但是对于不同的子应用分别能有自己的RequestProcessor实例每个RequestProcessor实例分别对应不同的struts配置文件。
子应用的ProcessorClass类必须重写一般就是继承RequestProcessor类,然后再其配置文件的controller元素中的<processorClass>属性中作出修改。那么当
getRequestProcessor(getModuleConfig(request)).process(request,response);就能根据request选择相应的moduleconfig,再根据其<processorClass>属性选择相应的RequestProcessor子类来处理相应的请求了。
posted @
2006-08-22 16:14 阿成 阅读(329) |
评论 (0) |
编辑 收藏
Tomcat的class加载的优先顺序一览
1.最先是$JAVA_HOME/jre/lib/ext/下的jar文件。
2.环境变量CLASSPATH中的jar和class文件。
3.$CATALINA_HOME/common/classes下的class文件。
4.$CATALINA_HOME/commons/endorsed下的jar文件。
5.$CATALINA_HOME/commons/i18n下的jar文件。
6.$CATALINA_HOME/common/lib 下的jar文件。
(JDBC驱动之类的jar文件可以放在这里,这样就可以避免在server.xml配置好数据源却出现找不到JDBC D
posted @
2006-08-22 16:11 阿成 阅读(219) |
评论 (0) |
编辑 收藏
http://www.databaseanswers.org/data_models/index.htm
posted @
2006-08-22 09:30 阿成 阅读(288) |
评论 (0) |
编辑 收藏
摘要: 1.
关于
hibernate
缓存的问题:...
阅读全文
posted @
2006-08-22 09:23 阿成 阅读(385) |
评论 (0) |
编辑 收藏
struts使用日期包括将string自动转化为日期fill到form中,以及将form中的日期按照指定格式显示在html的textfield中。首先讲第一种情况的解决方法:
创建如下类:
import java.util.*;
import org.apache.commons.beanutils.*;
import java.text.SimpleDateFormat;
public class DateConvert implements Converter
{
static SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
public DateConvert()
{
}
public Object convert(Class type, Object value)
{
if(value==null)return null;
if(((String)value).trim().length()==0) return null;
if(value instanceof String)
{
try
{
return df.parse((String)value);
}
catch (Exception ex)
{
throw new ConversionException("输入的日期类型不合乎yyyy/MM/dd"
+ value.getClass());
}
}
else
{
throw new ConversionException("输入的不是字符类型"+value.getClass());
}
}
}
然后在你的系统某出使用如下(如web的init方法)
ConvertUtils.register(new DateConvert(),java.util.Date.class);
参数用于表示DateConvert类负责处理java.util.Date类型的转化
第二种情况是如何显示form中日期类型到html:text中,我用的办法是修改struts的代码,重新生成一个新的struts.jar
org.apache.struts.taglib.html.BaseFieldTag的doStartTag的方法
找到 if (value != null) {results.append(ResponseUtils.filter(value))代码行下面的内容,需要修改此处代码,以便输出日期类型
如下:
if (value != null) {
results.append(ResponseUtils.filter(value));
} else if (redisplay || !"password".equals(type)) {
Object value = RequestUtils.lookup(pageContext, name, property, null);
//System.out.println("lijz "+value);
if(value instanceof java.util.Date)
{
//System.out.println("date="+value);
if (value == null)
value = "";
else
{
java.util.Date d= (java.util.Date)value;
try
{
results.append(ResponseUtils.filter(df.format(d)));
}
catch(Exception ex)
{
System.out.println("form error:"+ex.getMessage());
}
}
}
else
{
if (value == null)
value = "";
results.append(ResponseUtils.filter(value.toString()));
}
}
results.append("\"");
results.append(prepareEventHandlers());
results.append(prepareStyles());
results.append(getElementClose());
// Print this field to our output writer
ResponseUtils.write(pageContext, results.toString());
// Continue processing this page
return (EVAL_BODY_TAG);
重新编译struts成struts.jar.放到你需要的项目中
作者Blog:http://blog.csdn.net/chensheng913/
posted @
2006-08-21 16:02 阿成 阅读(230) |
评论 (0) |
编辑 收藏
1、将com
.regex.test转换成com/regex/test
用replaceAll转换
replaceAll中的第一个参数是一个正则表达示,不是普通的字符串组合
replaceAll("
.", "/") <===>Pattern.compile("
.")
.matcher(str)
.replaceAll("/")
"."需加转义符,要写成"\\.",如replaceAll("\\
.", "/") 即可。
posted @
2006-08-21 10:02 阿成 阅读(213) |
评论 (0) |
编辑 收藏
几乎每个企业都需要技术人员的支持,生产制造型企业需要现场生产控制和工艺流程方面的技术人才;IT等高科技行业需要大量软件研发和设备维护的硬件工程师;房地产、建筑工程领域需要建筑设计师、土木工程师和施工技术人员。此外,不论是国企、民营企业还是外资公司,都需要大量的基础技术工人。甚至很多在豪华写字楼office内工作的白领,从事的工作都是和技术相关的。
不过,一个严峻的现实是,大量的技术类人员对自己的职业定位和职业生涯规划显得非常迷茫和困惑。中国有句古话:劳心者治人,劳力者治于人。与管理类岗位相比,技术人员往往被人看低一等,他们虽然从事着非常重要、繁琐的技术性工作,但更多的是扮演着幕后英雄的角色。在社会地位、经济收入方面与分光无限的各级管理层普遍存在差距,这一现实造就了技术人员的巨大心理落差。第二个造成职业规划困惑的原因是部分技术性工作的局限性。拿IT行业来说,由于技术和知识更新的速度太快,软件开放人员普遍被认为是吃“青春饭”的职位,谁学习的更快、谁的精力更旺盛、谁更能熬夜,谁就更有竞争力,因为这时经验已经不再重要。如果超过35岁还从事软件开发的话,将很难在本职岗位取得突破。
那么,对于技术类人员来说,难道他们的职业发展前景真的如此黯淡?事实当然不会如此悲观,做技术工作同样有着非常广阔的空间,当然,关键一点你要令自己的视野更开阔些,从长远的角度来看待这个问题。根据我的经验,技术人员的职业方向可以有以下几个选择:
方向一、成为项目经理
对于很多从事技术方面工作的人员来说,发展成为项目经理是一个相当好的工作。项目管理工作既需要扎实的技术背景支持,又涉及多方面的管理工作,最适合那些技术出身但又不甘于只做技术工作的人员。成为项目经理,一方面可以充分发挥技术人员的专业优势,同时又可在团队管理、协调各方资源、内外部沟通等工作中体验和发挥作为管理者的角色和作用,从而让自身价值更为充分的实现和得到认可。优秀的项目管理人才,也是今后很长时期内的一个热门职业方向。
方向二、成为行业资深专家
如果的确非常喜爱技术工作,而不擅长和喜欢与人沟通,则可以完全专注于自身的领域,以发展成为行业资深专家为方向和目标,当然,这一发展过程可能会比较漫长,任何一个领域的顶尖技术人才都需要长期的行业经验的累积和个人孜孜不倦的投入。不过这类人才的一个优势是越老越吃香,当别人随着年龄的逐步增长而开始担心饭碗问题时,你则渐入佳境,开始进入职业发展的黄金时期。
方向三、成为研发经理或技术总监
事实上,在某些行业和企业,技术研发人员的地位是非常高的。譬如在微软、诺基亚、华为等IT产业,技术的支持和研发的速度,成为企业利润增长的最主要来源,在这些行业,技术研发部门就是企业的主战场。在不少国企和政府部门,也非常重视科技和技术工作,例如,我所知道的广州市市政园林局,就设有总工程师、副总工程师等技术职位,其中总工程师的职务级别相当于副局级,在这种氛围影响下,技术岗位人才和行政领导同样受人尊敬。所以,在一个尊重和重视技术工作的行业和企业中,发展成为研发经理、技术总监或总工程师都是一个很好的选择。
方向四、做技术型销售和服务
技术工作的领域其实非常广泛,如果感觉纯技术工作发展潜力不大,可以考虑转向做销售或技术支持方面。华为、中兴等通信技术公司的销售人员,很少是不具有专业技术背景的;甲骨文等软件巨头的市场推广,第一步常常是从销售工程师拜访客户开始的。这类高价值、高科技的产品销售推广,非常需要具有丰富技术经验的销售人员。
技术人员转向售后服务,也是非常有前途的。我认识的一个朋友,大学是施工机械专业,毕业后一直在市政工程行业做非开挖顶管施工,在几年的工作中积累了丰富的地下顶进设备的应用和维修经验,一个合适的机会跳槽到著名的顶管设备生产商-德国海瑞克公司,成为其售后服务工程师,工作上得心应手,收入也有了数倍的增长。
方向五、转向管理岗位
总有一些人,虽然是理工科出身、从事着技术岗位工作,但他们似乎天生就是具有管理天赋的人。这些人会在工作中逐步展现出管理潜质和优秀的领导能力,他们往往更喜欢跟人打交道,更喜欢与外界沟通。在这种条件下,以技术经验为基础和依托,适当补充学习些管理方面的知识,例如可以在职攻读MBA,假以时日,完全可以成长为出色的职业经理人。
方向六、高级技术操作人员
刚才所谈的职业发展方向,适用群体多为高校理工专业出身的人士,但对于数量众多的中等专科学校、技校毕业的一线技术工人来说,成为行业技术专家或研发总监的机会显然非常微小。这一群体的职业人士,最佳的技术发展路线是立足本职岗位,成为高级操作型技术人员。
广州市2006年出台的各类岗位工资指导价格中,高级技师就业的工资比博士还要高出500元。出现这一现象的原因很简单,从全国层面来说,产业工人数量虽然巨大,但高级技工的比例却非常小,“高级技工”的缺乏已经成为制约许多企业发展的“瓶颈”。但随着政策环境、企业认识角度和培育机制方面的不断改善,这一现象将逐步得到改变,所以成为中高级技师将是一个非常有前途的职业发展方向。
最后,我再次拿IT行业为例来具体谈谈技术人员的职业轨迹。
IT(Information Technology)行业的分类相当复杂,我这里仅仅分析最典型的三个部分:
第一部分是软件开发,通俗来说就是编程。实际上我认为真正的软件开发人员和制鞋工厂中的工人处在一个地位,是企业产品的最终生产者(当然这里没有贬义)。
第二个部分是MIS: Management Information Service/System(管理信息系统),主要负责基础IT建设、网络、通讯、软硬件支持、简单开发等职能,为公司其他部门提供IT基础服务。
第三部分是ERP: Enterprise Resource Planning(企业资源计划系统),主要涉及企业管理类软件实施、维护、管理。通过是引入信息化手段在企业现实的实现企业的资源管理,协调企业各方面的生产运作,它对业务的规范和企业的管理机制有很大的依赖。
让我们来分别看看这三部分人员的职业发展空间:
1. 开发人员
我的观点是,在中小企业做纯粹的软件开发很可能走上一条不归路,长期从事开发的人一般处世能力不足,升任管理人员的机会不大。而还有一个更重要的问题是中国目前开发行业的环境很不好,正如我之前谈到的基本是在吃青春饭,30往后就很难做下去了。而在美国40岁的开发人员是正吃香的年龄。虽然可能业务越来越精,但可能会离IT越来越远,向纯蓝领工人发展。
如果真的要做开发,应该找一个更好的平台,最好是进入跨国企业或国内龙头企业。如果数据方面的技术很强,可以考虑转向互联网搜索方向;如果在电子和通信设备方面有优势,可以从简单的程序开发转向通信产品的开发。
2. MIS人员
MIS内容广泛,可从事的职业很多:网管、技术支持等,而且通过努力可以得到提升成为小小的主管(当然要有自身的素质),进而成为MIS Manager,但做到MIS Manager基本也就到头了,不过倒是可以考虑转到不同的行业或企业做MIS。
同样是做IT服务,在不同公司内IT部门的地位还是非常巨大的。就我所了解的,雅芳(中国)公司的IT部门就有100多人,在公司总部的各职能部门中的地位相当高;而南方航空公司的IT部门竟然达到800多人,这个规模已经远远超过一般的IT公司,其IT部门的总裁也是公司决策层的重要成员。所以,在这些公司内做IT技术支持工作,既避免了纯编程式的软件开发人员遇到的“人老珠黄”的被动局面,也不必担心IT产业泡沫破灭而产生的生存危机。
3. ERP类人员
从事企业管理类软件的人员一般起点比较高(公司的起点就比较高),要求对财务、生产、销售等流程都有清楚地认识,从业人员不一定为IT出身,而有可能是财务人员或理工科人员等转行而来。IT的迅速发展和企业经营领域的不断拓展,为ERP的推广和发展创造了良好的发展空间。事实上,一个从事企业管理类软件的技术人员完全可以胜任一个企业的管理者,在这一领域技术人员的前景可以说是非常广阔的。
我认识的一位朋友,本科读的是工业装备控制专业,毕业后一直从事ERP方面的应用推广和管理咨询,虽然他对纯粹的IT技术了解并不是特别深刻,但在ERP系统在企业中的应用方面经验非常丰富,在别人眼中他更像是一名管理咨询师,五年下来已经是这一领域的专家级人物,在个人收入方面也非常可观。
posted @
2006-08-21 08:53 阿成 阅读(186) |
评论 (0) |
编辑 收藏
Strategy策略模式是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类.
Stratrgy应用比较广泛,比如, 公司经营业务变化图, 可能有两种实现方式,一个是线条曲线,一个是框图(bar),这是两种算法,可以使用Strategy实现.
这里以字符串替代为例, 有一个文件,我们需要读取后,希望替代其中相应的变量,然后输出.关于替代其中变量的方法可能有多种方法,这取决于用户的要求,所以我们要准备几套变量字符替代方案.
首先,我们建立一个抽象类RepTempRule 定义一些公用变量和方法:
public abstract class RepTempRule{
protected String oldString=""; public void setOldString(String oldString){ this.oldString=oldString; }
protected String newString=""; public String getNewString(){ return newString; }
public abstract void replace() throws Exception;
} |
在RepTempRule中 有一个抽象方法abstract需要继承明确,这个replace里其实是替代的具体方法.
我们现在有两个字符替代方案,
1.将文本中aaa替代成bbb;
2.将文本中aaa替代成ccc;
对应的类分别是RepTempRuleOne RepTempRuleTwo
public class RepTempRuleOne extends RepTempRule{
public void replace() throws Exception{
//replaceFirst是jdk1.4新特性 newString=oldString.replaceFirst("aaa", "bbbb") System.out.println("this is replace one"); }
}
|
public class RepTempRuleTwo extends RepTempRule{
public void replace() throws Exception{
newString=oldString.replaceFirst("aaa", "ccc") System.out.println("this is replace Two"); }
} |
第二步:我们要建立一个算法解决类,用来提供客户端可以自由选择算法。
public class RepTempRuleSolve {
private RepTempRule strategy; public RepTempRuleSolve(RepTempRule rule){ this.strategy=rule; } public String getNewContext(Site site,String oldString) { return strategy.replace(site,oldString); } public void changeAlgorithm(RepTempRule newAlgorithm) { strategy = newAlgorithm; } } |
调用如下:
public class test{
......
public void testReplace(){
//使用第一套替代方案 RepTempRuleSolve solver=new RepTempRuleSolve(new RepTempRuleSimple()); solver.getNewContext(site,context);
//使用第二套
solver=new RepTempRuleSolve(new RepTempRuleTwo()); solver.getNewContext(site,context);
}
.....
}
|
我们达到了在运行期间,可以自由切换算法的目的。
实际整个Strategy的核心部分就是抽象类的使用,使用Strategy模式可以在用户需要变化时,修改量很少,而且快速.
Strategy和Factory有一定的类似,Strategy相对简单容易理解,并且可以在运行时刻自由切换。Factory重点是用来创建对象。
Strategy适合下列场合:
1.以不同的格式保存文件;
2.以不同的算法压缩文件;
3.以不同的算法截获图象;
4.以不同的格式输出同样数据的图形,比如曲线 或框图bar等
posted @
2006-08-18 09:09 阿成 阅读(271) |
评论 (0) |
编辑 收藏
一、表单验证的流程
在
hello.jsp
网页上,不输入姓名,直接单击【
Submit
】
按钮,会看到如图
2-6
所示的网页。
图
2-6
表单验证失败的
hello.jsp
网页
当客户提交
HelloForm
表单时,
请求路径为
“
/HelloWorld.do
”:
<html:form action="/HelloWorld.do" focus="userName" >
服务器端执行表单验证流程如下。
(
1
)
Servlet
容器在
web.xml
文件中寻找
<url-pattern>
属性为“
*.do
”的
<servlet-mapping>
元素:
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(
2
)
Servlet
容器依据以上
<servlet-mapping>
元素的
<servlet-name>
属性“
action
”,在
web.xml
文件中寻找匹配的
<servlet>
元素:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
</servlet>
(
3
)
Servlet
容器把请求转发给以上
<servlet>
元素指定的
ActionServlet
,
ActionServlet
依据用户请求路径
“
/HelloWorld.do
”,
在
Struts
配置文件中检索
path
属性为
“
/HelloWorld
”
的
<action>
元素
:
<action path = "/HelloWorld"
type = "hello.HelloAction"
name = "HelloForm"
scope = "request"
validate = "true"
input = "/hello.jsp"
>
<forward name="SayHello" path="/hello.jsp" />
</action>
|
更确切地说,
ActionServlet
此时检索的是
ActionMapping
对象,而不是直接访问
Struts
配置文件中的
<action>
元素。因为
在
ActionServlet
初始化的时候,会加载
Struts
配置文件,把各种配置信息保存在相应的配置类的实例中,例如
<action>
元素的配置信息存放在
ActionMapping
对象中。
|
(
4
)
ActionServlet
根据
<action>
元素的
name
属性,创建一个
HelloForm
对象,把客户提交的表单数据传给
HelloForm
对象,再把
HelloForm
对象保存在
<action>
元素的
scope
属性指定的
request
范围内。
(
5
)由于
<action>
元素的
validate
属性为
true
,
ActionServlet
调用
HelloForm
对象的
validate()
方法执行表单验证:
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if ((userName == null) || (userName.length() < 1))
errors.add("username", new ActionMessage("hello.no.username.error"));
return errors;
}
(
6
)
HelloForm
对象的
validate()
方法返回一个
ActionErrors
对象,里面包含一个
ActionMessage
对象,这个
ActionMessage
对象中封装了错误消息,消息
key
为“
hello.no.username.error
”
,
在
Resource Bundle
中与值匹配的消息文本为:
hello.no.username.error=Please enter a <i>UserName</i> to say hello to!
(
7
)
ActionServlet
把
HelloForm
的
validate()
方法返回的
ActionErrors
对象保存在
request
范围内,然后根据
<action>
元素的
input
属性,把客户请求转发给
hello.jsp
。
(
8
)
hello.jsp
的
<html:errors>
标签从
request
范围内读取
ActionErrors
对象,再从
ActionErrors
对象中读取
ActionMessage
对象,把它包含的错误消息显示在网页上。
二、
逻辑验证失败的流程
接下来在
hello.jsp
的
HTML
表单中输入姓名“
Monster
”,然后单击【
Submit
】
按钮。当服务器端响应客户请求时,验证流程如下。
(
1
)表单验证
的流程(
1
)~(
4
)。
(
2
)
ActionServlet
调用
HelloForm
对象的
validate()
方法,这次
validate()
方法返回的
ActionErrors
对象中不包含任何
ActionMessage
对象,表示表单验证成功。
(
3
)
ActionServlet
查找
HelloAction
实例是否存在,如果不存在就创建一个实例。然后调用
HelloAction
的
execute()
方法。
(
4
)
HelloAction
的
execute()
方法先进行逻辑验证,由于没有通过逻辑验证,就创建一个
ActionMessage
对象,这个
ActionMessage
对象封装了错误消息,消息
key
为“
hello.dont.talk.to.monster
”,在
Resource Bundle
中与值匹配的消息文本为:
hello.dont.talk.to.monster=We don't want to say hello to Monster!!!
execute()
方法把
ActionMessage
对象保存在
ActionMessages
对象中,再把
ActionMessages
对象存放在
request
范围内。最后返回一个
ActionForward
对象,该对象包含的请求转发路径为
<action>
元素的
input
属性指定的
hello.jsp
。
以下是
execute()
方法中进行逻辑验证的代码:
ActionMessages errors = new ActionMessages();
String userName = (String)((HelloForm) form).getUserName();
String badUserName = "Monster";
if (userName.equalsIgnoreCase(badUserName)) {
errors.add("username", new ActionMessage("hello.dont.talk.to.monster", badUserName ));
saveErrors(request, errors);
return (new ActionForward(mapping.getInput()));
}
(
5
)
ActionServlet
依据
HelloAction
返回的
ActionForward
对象,再把请求转发给
hello.jsp
。
(
6
)
hello.jsp
的
<html:errors>
标签从
request
范围内读取
ActionMessages
对象,再从
ActionMessages
对象中读取
ActionMessage
对象,把它包含的错误消息显示在网页上,
如图
所示。
逻辑验证失败时的
hello.jsp
网页
三
、逻辑验证成功的流程
接下来,在
hello.jsp
的
HTML
表单中输入姓名“
Weiqin
”,然后单击【
Submit
】
按钮。当服务器端响应客户请求时,流程如下。
(
1
)重复
二
的流程(
1
)~(
3
)。
(
2
)
HelloAction
的
execute()
方法先执行逻辑验证,这次通过了验证,然后执行相关的业务逻辑,最后调用
ActionMapping.findForward()
方法,参数为
“
SayHello
”:
// Forward control to the specified success URI
return (mapping.findForward("SayHello"));
(
3
)
ActionMapping.findForward()
方法从
<action>
元素中寻找
name
属性为
“
SayHello
”的
<forward>
子元素,然后返回与之对应的
ActionForward
对象,它代表的请求转发路径为“
/hello.jsp
”。
|
更确切地说,
ActionMapping
从本身包含的
HashMap
中查找
name
属性为
“
SayHello
”
的
ActionForward
对象。在
ActionServlet
初始化时会加载
Struts
配置文件,把
<action>
元素的配置信息存放在
ActionMapping
对象中。
<action>
元素中可以包含多个
<forward>
子元素,每个
<forward>
子元素的配置信息存放在一个
ActionForward
对象中,这些
ActionForward
对象存放在
ActionMapping
对象的
HashMap
中。
|
(
4
)
HelloAction
的
execute()
方法
然后把
ActionForward
对象返回给
ActionServlet
,
ActionServlet
再把客户请求转发给
hello.jsp
。
(
5
)
hello.jsp
的
<bean:message>
标签从
Resource Bundle
中读取文本,把它们输出到网页上,最后生成
动态网页,如图
所示。
通过数据验证的
hello.jsp
网页
posted @
2006-08-17 20:22 阿成 阅读(1895) |
评论 (0) |
编辑 收藏
1、JSP页面编码
<%@ page contentType="text/html;charset=........"%>
<%@ page language="java" pageEncoding="........"%>
pageEncoding:The encoding used for the JSP page file, as well as
the response charset if no charset is specified by contentType.
If this attribute is omitted, but a charset is specified for contentType,
that charset is also used of the page; if contentType doesn't specify a
charset, ISO-8859-1 is used for a regular JSP page, and UTF-8 is used
for a JSP Document.
posted @
2006-08-17 10:09 阿成 阅读(356) |
评论 (0) |
编辑 收藏