posts - 10, comments - 9, trackbacks - 0, articles - 17

2010年7月29日

[ERROR] 07-29 11:23 - The /WEB-INF/web.xml was not found.  (ActionServlet.java:1787)
java.net.ConnectException: Connection timed out: connect

原web.xml头部:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>




  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>


修改为
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">




  
<servlet>
    
<servlet-name>action</servlet-name>
    
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

posted @ 2010-07-29 11:23 wesley1987 阅读(1474) | 评论 (0)编辑 收藏

2010年7月28日


在tomcat等容器中发布带velocity的应用时, 出现 org.apache.velocity.exception.ResourceNotFoundException : Unable to find resource ...vm  的解决办法:

配置文件 velocity.properties 中, 如果有
resource.loader = file

file
.resource.loader.description = Velocity File Resource Loader
file
.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file
.resource.loader.path = .
file
.resource.loader.cache = false
file
.resource.loader.modificationCheckInterval = 2

这段, 全部注释掉即可.

若没有, 就在配置里写上以上内容, 并更改第三项为

file.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader

posted @ 2010-07-28 15:35 wesley1987 阅读(14015) | 评论 (1)编辑 收藏

1。指定velocity.properties文件,  默认路径为 WEB-INF/velocity.properties 也可自定义路径, 在web.xml中
      <servlet>
        
<servlet-name>velocity</servlet-name>
        
<servlet-class>org.apache.velocity.tools.view.servlet.VelocityLayoutServlet</servlet-class>
        
<init-param>
            
<param-name>org.apache.velocity.properties</param-name>
            
<param-value>/WEB-INF/config/velocity.properties</param-value>
        
</init-param>
        
<init-param>
            
<param-name>org.apache.velocity.toolbox</param-name>
            
<param-value>/WEB-INF/config/velocity-toolbox.xml</param-value>
        
</init-param>
        
<load-on-startup>5</load-on-startup>
      
</servlet>
注意 load-on-startup 需要配置且靠后, 否则启动时看不到日志.

2。在velocity.properties中配置日程相关参数:
#----------------------------------------------------------------------------
#  default LogSystem to use: default: AvalonLogSystem
#----------------------------------------------------------------------------


runtime
.log.logsystem.class = org.apache.velocity.runtime.log.SimpleLog4JLogSystem

runtime
.log.logsystem.log4j.category = velocity_log

#----------------------------------------------------------------------------
# This controls if Runtime.error(), info() and warn() messages include the
# whole stack trace. The last property controls whether invalid references
# are logged.
#----------------------------------------------------------------------------


runtime
.log.error.stacktrace = false
runtime
.log.warn.stacktrace = false
runtime
.log.info.stacktrace = false
runtime
.log.invalid.reference = true


3\ 配置log4j.properties,  具体配置意义请参看log4j配置相关文档
log4j.rootLogger=INFO,CONSOLE,FILE
log4j
.logger.velocity_log=INFO,CONSOLE,VELOCITY
log4j
.addivity.org.apache=true

log4j
.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j
.appender.CONSOLE.Threshold=WARN
log4j
.appender.CONSOLE.Target=System.out
log4j
.appender.CONSOLE.Encoding=GBK
log4j
.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j
.appender.CONSOLE.layout.ConversionPattern=[%-4p] %d{MM-dd HH:mm} - %m  %n

log4j
.appender.VELOCITY=org.apache.log4j.FileAppender
log4j
.appender.VELOCITY.File=E:/workspace/dwrt/WebRoot/log/velocity.log
log4j
.appender.VELOCITY.Append=false
log4j
.appender.VELOCITY.Encoding=GBK
log4j
.appender.VELOCITY.layout=org.apache.log4j.PatternLayout
log4j
.appender.VELOCITY.layout.ConversionPattern=[%-4p] %d{MM-dd HH:mm} - %m  %n

posted @ 2010-07-28 11:39 wesley1987 阅读(2444) | 评论 (0)编辑 收藏

2010年7月7日

select COUNT(*) from table t WHERE t.col <> '3'


SELECT COUNT(*) FROM table t WHERE t.col NOT IN
(select t.col from table t WHERE t.col= '3')

以上两句SQL的执行结果不同, 因为 <> 在排除3的同时, 将null也排除了,
所以当比较字段含null时,第一句将比第二句的结果少.

当然第二句从效率上来说不是一个好的写法, 这样写只是为了理解, 在第一句后面, 加上 or t.col is null 应该就等效了.

posted @ 2010-07-07 10:17 wesley1987 阅读(7279) | 评论 (1)编辑 收藏

在js中写了个替换字符的句子, 然后才知道原来js没有replaceAll方法, 就是说用replace的话, 他自会替换一次.

自定义replaceAll方法,
String.prototype.replaceAll  = function(s1,s2){    
        return this.replace(new RegExp(s1,"gm"),s2);   
}  

gm     g=global, m=multiLine  , 

或直接 string = string..replace(new RegExp(s1,"gm"),s2);   

posted @ 2010-07-07 09:44 wesley1987 阅读(1057) | 评论 (0)编辑 收藏

2009年7月27日

在使用DispatchAction时出现了这个问题,从这句话分析,就是没有在指定的类中,找到对应的方法。

先说结论: 在Action中定义的方法(要在参数中使用的方法),参数一定要固定为
(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response )

--------------------------------
这种错误,一般在保证所有路径的拼写都正确的情况下应该就能避免,

那接着分析一下,struts是如何从jsp一步步找到这个方法呢?


1 页面上 action的路径,以及对应的struts配置文件中定义的parameter的参数名(我这叫method)属性值,这个属性值应对应着 Action类的方法名。

2 确认了以上路径都正确的情况下,考虑到DispatchAction对应“方法”的方式,发现原来是方法多了一个参数。

顺便看了下DispatchAction源代码,看到里面找方法的时候,用的是
 method = clazz.getMethod(name, types);
其中
clazz = getClass();
types = (new Class[] {
            org.apache.struts.action.ActionMapping.class,  org.apache.struts.action.ActionForm.class,  javax.servlet.http.HttpServletRequest.class,  javax.servlet.http.HttpServletResponse.class
        });

就是说,DispatchAction只会将参数固定为以上4中的函数作为控制器方法使用。

posted @ 2009-07-27 21:13 wesley1987 阅读(4207) | 评论 (2)编辑 收藏

2009年4月21日

选自 http://java.chinaitlab.com/Spring/762022.html

 Spring Security使用一组过滤器链来对用户进行身份验证和授权。首先,在web.xml文件中添加FilterToBeanProxy过滤器配置:
 1 <filter>   
 2       <filter-name>springSecurityFilterChain</filter-name>
 3      <filter-class>
 4         org.springframework.security.util.FilterToBeanProxy
 5      </filter-class>
 6      <init-param>       
 7           <
param-name>targetClass</param-name>
 8          <param-value>           
 9               org.springframework.security.util.FilterChainProxy
10          </param-value>
11       </init-param>
12 </filter>
13
        org.springframework.security.util.FilterToBeanProxy实现了Filter接口,它通过调用WebapplicationContextUtils类的getWebApplicationnContext(servletContext)方法来获取Spring的应用上下文句柄,并通过getBean(beanName)方法来获取Spring受管Bean的对象,即这里targetClass参数配置的Bean,并通过调用FilterChain Proxy的init()方法来启动Spring Security过滤器链进行各种身份验证和授权服务(FilterChainProxy类也是实现了Filter接口),从而将过滤功能委托给Spring的FilterChainProxy受管Bean(它维护着一个处理验证和授权的过滤器列表,列表中的过滤器按照一定的顺序执行并完成认证过程),这样即简化了web.xml文件的配置,又能充分利用 Spring的IoC功能来完成这些过滤器执行所需要的其它资源的注入。

        当用户发出请求,过滤器需要根据web.xml配置的请求映射地址来拦截用户请求,这时Spring Security开始工作,它会验证你的身份以及当前请求的资源是否与你拥有的权限相符,从而达到保护Web资源的功能,下面是本例所要过滤的用户请求地址:
 1 <filter-mapping>
 2 
 3        <filter-name>springSecurityFilterChain</filter-name>

 5        <url-pattern>/j_spring_security_check</url-pattern>
 6 
 7     </filter-mapping>
 8 
 9     <filter-mapping>
10 
11        <filter-name>springSecurityFilterChain</filter-name>
12 
13        <url-pattern>/*</url-pattern>
14 
15 </filter-mapping>

提示:
/j_spring_security_check是Spring Security默认的进行表单验证的过滤地址,你也可以修改为别的名称,但是需要和
applicationContext-security.xml中相对应,当然还会涉及到其它一些默认值(可能是一个成员变量,也可能是别的请
求地址),在下文我们将看到,建议你在阅读此文的同时,应该参照Spring Security项目的源代码,便于你更好的理解。


3 配置applicationContext-security.xml

    3.1 FilterChainProxy过滤器链

    FilterChainProxy会按顺序来调用一组filter,使这些filter即能完成验证授权的本质工作,又能享用Spring Ioc的功能来方便的得到其它依赖的资源。FilterChainProxy配置如下:

 1 <bean id="filterChainProxy"   
        class
="org.springframework.security.util.FilterChainProxy">
 2      <property name="filterInvocationDefinitionSource">
 3         <value><![CDATA[         
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 
 4              PATTERN_TYPE_APACHE_ANT         
                /**=httpSessionContextIntegrationFilter,logoutFilter,
 5              authenticationProcessingFilter,securityContextHolderAwareRequestFilter,
 6              rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,
 7              filterSecurityInterceptor 
 8         ]]></value>
 9      </property>
10 </bean>

    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 定义URL在匹配之前必须先转为小写,PATTERN_TYPE_APACHE_ANT 定义了使用Apache ant的匹配模式,/**定义的将等号后面的过滤器应用在那些URL上,这里使用全部URL过滤,每个过滤器之间都适用逗号分隔,它们按照一定的顺序排列。

 
提示:
特别需要注意的是,即使你配置了系统提供的所有过滤器,这个过滤器链会很长,但是千万不要使用换行,否则它们不会正常工作,
容器甚至不能正常启动。
 

    下面根据FilterChainProxy的配置来介绍各个过滤器的配置,各个过滤器的执行顺序如以上配置。

    首先是通道处理过滤器,如果你需要使用HTTPS,这里我们就使用HTTP进行传输,所以不需要配置通道处理过滤器,然后是集成过滤器,配置如下:

1 <bean id="httpSessionContextIntegrationFilter"
2 
3 class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>

    httpSessionContextIntegrationFilter是集成过滤器的一个实现,在用户的一个请求过程中,用户的认证信息通过SecurityContextHolder(使用ThreadLoacl实现)进行传递的,所有的过滤器都是通过SecurityContextHolder来获取用户的认证信息,从而在一次请求中所有过滤器都能共享Authentication(认证),减少了HttpRequest参数的传送,下面的代码是从安全上下文的获取Authentication对象的方法:

1 SecurityContext context = SecurityContextHolder.getContext();
2 
3 Authentication authentication = context.getAuthentication();

    但是,ThreadLoacl不能跨越多个请求存在,所以,集成过滤器在请求开始时从Http会话中取出用户认证信息并创建一个SecurityContextHolder将Authentication对象保存在其中,在请求结束之后,在从SecurityContextHolder中获取Authentication对象并将其放回Http会话中,共下次请求使用,从而达到了跨越多个请求的目的。集成过滤器还有其它的实现,可以参考相关文档。

提示:
集成过滤器必须在其它过滤器之前被使用。
 

    logoutFilter(退出过滤器) ,退出登录操作:

 1 <bean id="logoutFilter"
 2 
 3     class="org.springframework.security.ui.logout.LogoutFilter">
 4 
 5     <constructor-arg value="/index.jsp"/>
 6 
 7     <constructor-arg>
 8 
 9        <list>
10 
11            <!-- 实现了LogoutHandler接口(logout方法) -->
12 
13            <ref bean="rememberMeServices"/>
14 
15            <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
16 
17        </list>
18 
19     </constructor-arg>
20 
21 </bean>


posted @ 2009-04-21 16:11 wesley1987 阅读(598) | 评论 (0)编辑 收藏

2008年12月23日

 

                  项目实训心得

             在这一个多月的项目实训过程,我感到是我专业学习中收获非常大的一个月。在这个月里,我体验到了团队合作的经验,编程过程中的乐趣,以及将学习应用到实际、从实践中学习的丰收感。

              这一个月里,得到了二个最宝贵体验:一是参与了一个团队合作的、有很强多同模块相互性、和一套完整生命周期流程的工程项目。这一套项目按照软件工程的流程一步步走下来,经历了需求分析,详细设计,实际编码和测试这一系列阶段。一步一步慢慢的走下来。虽然对于真实的项目来说,这个项目的复杂度和规模并不是很大,逻辑要求也不是太严格。但是对于只参加一些3-4人的项目编程的我来说,已经第一次让我体真正的体验到将编程作为一项工程来执行的难得经验。

              第二个体验是详细设计中,将软件架构和分层的思想以及简单的工程模式等应用到了项目中。使用框架等方式,非常有效的提高了代码的复用和工程的可维护性,虽然多层结构看似麻烦,但实际上它很大的降低了设计的复杂度,在实际的体验中感到,使用了框架后的模块,维护起来清晰了很多,容易了很多,降低了耦合,同时增强了模块间的交互和重用。

              随着整个工程的流程一步步进行,我们看到了一个工程的一次次成长。项目伊始,我们得到了项目需求文档(我想这一步在实际中也应该是由项目人员精心设计才完成的),对于工程的不同用例,将工程分为了六个模块,并对应的将组员分为了六组。我们的第一步是完成对需求文档的理解,而成果就是对应了各个模块的实际功能的静态页面,因为软件客户最后体验所有需求的功能实现就是通过操作页面来实现,所以页面要在客户需求的角度去考虑,同时要将需求的功能都赋予体现。在这个过程中,大家除了按功能分化出页面分类外,大部分时间还用来精心设计页面的风格。页面布局和菜单中大量用到了JavaScriptCSS。和以我往设计页面时不同的是,为了让大家可以公用这些设计,在页面的布局中不能太复杂,甚至几乎是不能在需要统一的地面对整体的布置有任何复杂的干预。所有希望统一的部分都要在公共的CSSJavaScript中做出方便统一使用的类或方法,在页面本身的代码中几乎看不到布局设计,只有功能组件。

              在页面设计通过审核之后就是详细设计阶段了,在这阶段的前几天我们犯了一个顺序错误,直接从数据库着手。结果由于项目的功能的复杂性和模块之间太多需要交互的地方,使得数据库的设计进行的很缓慢。经过老师的提点我们改为从程序编码的框架开始着手。联系各功能的具体实现来设计编码的层次结构(框架详细设计在下一节),划分出公共平台。这样再从各模块的功能及其交互划分来联系设计数据库就变的清晰了很多。在设计过程中我们还使用了E-R图来设计出关系数据库,即从参与的对象和对象之间的关系最终设计出数据库的方法。在这次设计中发现自己在利用一些系统的理论进行整体的数据库模型设计方面还存在很多不足。数据库完成后,对框架的设计也基本完成,公共的分页设计,数据库连接与关闭,工程的文件结构和工程的环境也在几次讨论后完成统一设计。

              由于之前对struts有了一定的了解,所以我在需求分析阶段就开始尝试着着手对几个简单模块的实现编码,之后在详细设计阶段中,每次讨论后新加的内容都需要对已经完成的代码进行一次大的修改。随着代码的增长,尝试了很多种文件结构。之后引入项目的框架也经历了很大的修改和许多次的尝试。此外的修改还包括BaseAction的引入,DispatchAction的引入,使用struts异常处理等,并做好工程备份及将修改记录在日报中。在这一次次的修改中让我受益匪浅,对这些设计和修改有了更深刻的体会。这样在详细设计阶段的过程中,框架设计都已经在编码中事先进行了实现和测试,一些功能在写好后被分离出来作为公共平台。终于在小组开始编码时确定出了统一并详细完整的的工程的全部环境,项目的框架结构和整体编码方式。我的编码实现和单元测试也基本完成。

              在两周的编码过程中,我主要是和吉利一起协助各模块编码,增加各模块间交流,在这期间也解决问题的过程中学到知识。经过全体组员两周的努力工作,终于进入了测试阶段。我和吉利负责整体测试,测试联结了所有模块之后,可以顺利的完成全套的流程。让整个设计可以在6个流程中一步步的走下去,同时保证数据库中所有数据和状态的正确性。随着测试一次次的进行,问题渐渐被全部排除,经过3次测试之后,基本可以完全顺利的走完全套流程。

               

              我们这次工程中使用的是四层结构的框架,即将MVC三层结构的同时,将model模型层分成了model模型层和DAO持久层。其中又根据工厂模式分出DAO接口,beanfactoryservicemanager)提供DAO实现。

              结构实现:首先我们根据框架,设计出相应的文件结构。视图层即所有JSP文件,和配置文件一起由eclipse的自动生成单独分在WebRoot下,六模块的页面分别分于六个子目录下。所有的公共页面和jscss目录也放入WebRoot下。由于这次项目中模块间的功能页面基本是完全相互独立的,这为在实现视图层和控制层之间的页面跳转控制带来很大的方便。代码目录(src)下为六个模块的六个目录,公共代码目录(platform),以及后加入的验证模块的目录(validate)。除公共目录外,各模块下代码分为5个目录:ActionmodelFormmanagerdao。(这里有两个命名的失误,根据实际的使用,model的名字应该叫bean更合适,而这里manager一般在框架中称为service。但我们已经有了称为service的模块名称。)这里的ActionForm对应了struts中的组件,DAO层和model-bean一起完成了操作的具体实现,

              视图层view:总体框架上,我们使用的是frameset来实现,不过听老师说现在流行的使用japinclude结合div等来实现页面框架。在之后编码中,因为frameset出现了一个问题,就是用来验证拦截的过滤器无法刷新整个框架,使得拦截后的页面只能显示在被操作的frame中。但是frameset的好处是框架分离的很好,在实现jsp编码中几乎完全不用去考虑框架。我不知道用include是否能做到。以前虽然都使用的include,但是是在每个页面中都要加入include。有时还会影响布局。在编码过程中,我们用JavaScript实现了很多很好用的效果,比如选择时间的窗口,表单的正则表达式验证,表格的变色效果等,封装到公共的js文件中,调用起来很方便。在这次jap编程中,我终于由最初的在页面中堆满java代码,转变为只使用一些JSTLEL语句和struts标签处理逻辑,美观了页面编码,同时让页面更专注于显示层。但这里我对EL语句和纯标签语句又有些难以取舍。EL语句在页面代码中虽然不如单用标签显得纯粹美观,但是EL表达式简约的表现风格让实现和维护变得容易了很多。

              控制层Action的设计一是使用了DispatchAction,将多个Action类合并,方便了管理。二在公共部分中定义了BaseAction,由这个类去继承strutsDispatchAction。之后我们的所有Action都去继承这个BaseAction。这样在需要对Action进行统一处理,以及定义一些供Action公共使用的方法时就可以在这个BaseAction中修改。虽然在这次项目中,BaseAction只定义了个用于处理字符乱码的方法公共使用,但由此即可瞥见对于更复杂的Action统一处理这种设计也能从容应对。由于是分模块进行,于是我们将strutsxml配置文件也分为对应各个模块,使用多xml的配置方式,而这也需要对命名规则等很多方面有更好的协调和统一。在这次控制层的实现中,我起初还是像以前一样对很多不同的验证,模型层返回的异常都在Action中处理并跳转。在之后的修改中,逐渐将这些处理都改至模型层Manager中,由Manager取用持久层的操作方法,实现所有业务逻辑处理。

              具体实现功能的模型层中,我们为每个DAO定义了接口和实现类,这也是我第一次将接口真正应用到程序中。同时我们在每个模块的DAO中应用了工厂模式,由一个factory类实现所有DAO的单例生成。之后在Manager中调用这个实例实现操作。而这个Manager同时本身也是单例实现的,由Action进行静态调用。可见其中实现Action控制层和DAO持久层交互的就是Manager模型层,并将两者严格的分离开来。同时在Manager中还集合处理了所有来至业务功能逻辑和底部数据库的所有异常。因为数据库的连接也是在Manager中创建的,但这不影响持久层的独立性,因为这是考虑到有时一次业务操作会进行多个数据库操作、调用多个数据库方法,将连接在模型层中创建更便于数据库的高效使用。模型层中对异常的集中处理,更简化了上下控制层和模型层的实现,使其更专注于各自的业务实现。在异常处理上,使用了struts的一种异常处理机制,在xml配置文件中进行异常配置。这样在Manager中将异常抛出,由struts实现异常跳转和提示。同时我们还将自定义的异常处理类也作为公共类公用,这样就可以在需要的时候对异常进行统一的处理。

              在持久层的实现上,我们使用了tomcat数据库连接池,在编码中将数据库连接等方法封装到公共类中,并且将连接数据源作静态单例实现,以提高数据库调用的效率。在DAO的设计方面,我们主要针对实际的操作对象和对应的数据库进行DAO层方法的封装。每个方法尽量实现一些简单的操作。这样在不同模块直接有数据和操作交互的时候,只在模型层只要去各个模块的DAO中取得需要的方法加以组合,实现自己的业务处理。很好的提高了代码的复用性和可维护性,降低了各个模块间数据交互处理的设计复杂度。

    //文采太烂, 结尾的感慨段就不发了

posted @ 2008-12-23 21:38 wesley1987 阅读(726) | 评论 (0)编辑 收藏

2008年12月15日

今天一个诡异的问题弄了我半天,最后发现原因如下:

在HTML的head中 引入外部script:
        <script src="<%=path%>/js/service.js" type="text/javascript" ></script>
之后又写内部script (内容无关)
<script type="text/javascript">
  function SecondType(){
  if (document.check.classTwo.value==1){
   stext.style.display="inline";
  }

  else{
   stext.style.display="none";
  }

 }

 function FirstType(select,forwards){
  if (document.check.classOne.value==1){
    ftext.style.display = "inline";
    document.check.classTwo.value=1;
    SecondType();
  }
else{
   ftext.style.display = "none";
   window.location="<%=path%>/service/good.do?operation=getClass&classone="+select.value+"&forward="+forwards; 
  }

 }

</script>
一切正常,
但是 如果将head中的改为
<script src="<%=path%>/js/service.js" type="text/javascript"  />变了下结尾
引入的外部script任然好用,但是下面的内部script就完全不执行。并伴随很多奇怪的显示效果。

posted @ 2008-12-15 19:21 wesley1987 阅读(544) | 评论 (0)编辑 收藏

转自网上的一篇很详细的关于servlet中各种出现乱码的问题即解决方案:
http://www.diybl.com/course/3_program/java/javajs/200829/99730.html

(1)前言:
解决web程序的国际化问题,必须在任何地方使用UTF-8对字符进行编码。(包括:数据库设置为:UTF-8,web页面也要设置为:UTF-8)
这样做的好处在于可以解决在web上不止中文字符编码问题,所有的字符编码都统一使用UTF-8,实现了语言的国际化。同时在保存数据到
数据库时候也省去了编码转换的问题。
在JSP或JSF应用中使用到Servlet,我们通过使用Servlet过滤器进行编码转换,也就是制定编码转换为UFT-8。

(2)Servlet和JSP过滤器Filter简介:
servlet API的2.3版本中最重要的一个新功能就是能够为servlet和JSP页面定义过滤器。过滤器提供了某些早期服务器所支持的非标准“servlet链接”的一种功能强大且标准的替代品。
过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择:
- 以常规的方式调用资源(即,调用servlet或JSP页面)。
- 利用修改过的请求信息调用资源。
- 调用资源,但在发送响应到客户机前对其进行修改
- 阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。
过滤器提供了几个重要好处。
     首先,它以一种模块化的或可重用的方式封装公共的行为。你有30个不同的serlvet或JSP页面,需要压缩它们的内容以减少下载时间吗?没问题:构造一个压缩过滤器(参阅第11节),然后将它应用到30个资源上即可。
    其次,利用它能够将高级访问决策与表现代码相分离。这对于JSP特别有价值,其中一般希望将几乎整个页面集中在表现上,而不是集中在业务逻辑上。例如,希望阻塞来自某些站点的访问而不用修改各页面(这些页面受到访问限制)吗?没问题:建立一个访问限制过滤器(参阅第8节)并把它应用到想要限制访问的页面上即可。
    最后,过滤器使你能够对许多不同的资源进行批量性的更改。你有许多现存资源,这些资源除了公司名要更改外其他的保持不变,能办到么?没问题:构造一个串替换过滤器(参阅第10节),只要合适就使用它。
    但要注意,过滤器只在与servlet规范2.3版兼容的服务器上有作用。如果你的Web应用需要支持旧版服务器,就不能使用过滤器。
建立一个过滤器涉及下列五个步骤:
1、建立一个实现Filter接口的类。这个类需要三个方法,分别是:doFilter、init和destroy。doFilter方法包含主要的过滤代码,init方法建立设置操作,而destroy方法进行清楚。
2、在doFilter方法中放入过滤行为。doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为FilterChain,如下一步所述,此参数用来调用servlet或JSP页。
3、调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
4、对相应的servlet和JSP页面注册过滤器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素。
5、禁用激活器servlet。防止用户利用缺省servlet URL绕过过滤器设置。

doFilter方法:

1 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
2  throws ServletException, IOException
3 {
4  HttpServletRequest req = (HttpServletRequest)request;
5  System.out.println(req.getRemoteHost() + " tried to access " +req.getRequestURL() +" on " + new Date() + ".");
6  chain.doFilter(request,response);
7 }


在web.xml中进行部署
分别是:filter和filter-mapping。filter元素向系统注册一个过滤对象,filter-mapping元素指定该过滤对象所应用的URL。

<filter>
<filter-name>ChangeCodeFilter</filter-name>
<display-name>ChangeCodeFilter</display-name>
<description></description>
<filter-class>com.cnc.SetCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<url-pattern>/SetCharacterEncodingFilter</url-pattern>
</filter-mapping>

1.filter元素
filter元素位于部署描述符文件(web.xml)的前部,所有filter-mapping、servlet或servlet-mapping元素之前。filter元素具有如下六个可能的子元素:
 :icon  这是一个可选的元素,它声明IDE能够使用的一个图象文件。
 : filter-name  这是一个必需的元素,它给过滤器分配一个选定的名字。
 : display-name  这是一个可选的元素,它给出IDE使用的短名称。
 : description  这也是一个可选的元素,它给出IDE的信息,提供文本文档。
 : filter-class  这是一个必需的元素,它指定过滤器实现类的完全限定名。
 : init-param  这是一个可选的元素,它定义可利用FilterConfig的getInitParameter方法读取的初始化参数。单个过滤器元素可包含多个init-param元素。
2.filter-mapping元素
  filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三个可能的子元素::
  filter-name 这个必需的元素必须与用filter元素声明时给予过滤器的名称相匹配。
  url-pattern  此元素声明一个以斜杠(/)开始的模式,它指定过滤器应用的URL。所有filter-mapping元素中必须提供url-pattern或servlet-name。但不能对单个filter-mapping元素提供多个url-pattern元素项。如果希望过滤器适用于多个模式,可重复整个filter-mapping元素。
:servlet-name  此元素给出一个名称,此名称必须与利用servlet元素给予servlet或JSP页面的名称相匹配。不能给单个filter-mapping元素提供多个servlet-name元素项。如果希望过滤器适合于多个servlet名,可重复这个filter-mapping元素。

(3)在Rational Application Developer 中的建立字符转换过滤器:
1.新建-web-过滤器:SetCharacterEncodingFilter
会在web.xml中产生如上代码:

2.在过滤器的doFilter方法中添加如下代码:

public void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {
  arg0.setCharacterEncoding(
"UTF-8"); //设定字体编码为UTF-8
  arg2.doFilter(arg0, arg1);// 传递控制到下一个过滤器
 }

3.在web.xml中进行部署
在web.xml的过滤器-编辑器中选择:servlet 映射 - 添加 - Faces Servlet
会在web.xml中产生如下代码:
<filter-mapping>
<filter-name>SetCharacterEncodingFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

(4)其他参考信息
tomcat下中文的彻底解决
(一)    JSP页面上是中文,但是看的是后是乱码:
解决的办法就是在JSP页面的编码的地方<%@ page language="java" contentType="text/html;charset=GBK" %>,因为Jsp转成Java文件时的编码问题,默认的话有的服务器是ISO-8859-1,如果一个JSP中直接输入了中文,Jsp把它当作ISO8859-1来处理是肯定有问题的,这一点,我们可以通过查看Jasper所生成的Java中间文件来确认
(二)    当用Request对象获取客户提交的汉字代码的时候,会出现乱码:
解决的办法是:要配置一个filter,也就是一个Servelet的过滤器,代码如下:

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
/**
 * Example filter that sets the character encoding to be used in parsing the
 * incoming request
 
*/
public class SetCharacterEncodingFilter implements Filter {
    
/**
     * Take this filter out of service.
     
*/
    
public void destroy() {
    }
    
/**
     * Select and set (if specified) the character encoding to be used to
     * interpret request parameters for this request.
     
*/
    
public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain)
throws IOException,ServletException {
    request.setCharacterEncoding(
"GBK");
    
// 传递控制到下一个过滤器
    chain.doFilter(request, response);
    }
    
public void init(FilterConfig filterConfig) throws ServletException {
    }
}

 

 

配置web.xml

<
filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>SetCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

如果你的还是出现这种情况的话你就往下看看是不是你出现了第四中情况,你的Form提交的数据是不是用get提交的,一般来说用post提交的话是没有问题的,如果是的话,你就看看第四中解决的办法。
还有就是对含有汉字字符的信息进行处理,处理的代码是:
package dbJavaBean;
public class CodingConvert
{  
 public CodingConvert()
 {
  //
 }
 public String toGb(String uniStr){
     String gbStr = "";
     if(uniStr == null){
   uniStr = "";
     }
     try{
   byte[] tempByte = uniStr.getBytes("ISO8859_1");
   gbStr = new String(tempByte,"GB2312");
     }
  catch(Exception ex){
    }
     return gbStr;
 }
  
 public String toUni(String gbStr){
     String uniStr = "";
     if(gbStr == null){
   gbStr = "";
     }
     try{
   byte[] tempByte = gbStr.getBytes("GB2312");
   uniStr = new String(tempByte,"ISO8859_1");
     }catch(Exception ex){
    }
    return uniStr;
 }
}
你也可以在直接的转换,首先你将获取的字符串用ISO-8859-1进行编码,然后将这个编码存放到一个字节数组中,然后将这个数组转化成字符串对象就可以了,例如:
String str=request.getParameter(“girl”);
Byte B[]=str.getBytes(“ISO-8859-1”);
Str=new String(B);
通过上述转换的话,提交的任何信息都能正确的显示。
(三)    在Formget请求在服务端用request. getParameter(“name”)时返回的是乱码;按tomcat的做法设置Filter也没有用或者用request.setCharacterEncoding("GBK");也不管用问题是出在处理参数传递的方法上:如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法进行处理的话前面即使是写了:
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
也是不起作用的,返回的中文还是乱码!!!如果把这个函数改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。
同样,在用两个JSP页面处理表单输入之所以能显示中文是因为用的是post方法传递的,改成get方法依旧不行。
由此可见在servlet中用doGet()方法或是在JSP中用get方法进行处理要注意。这毕竟涉及到要通过浏览器传递参数信息,很有可能引起常用字符集的冲突或是不匹配。
解决的办法是:
1) 打开tomcat的server.xml文件,找到区块,加入如下一行:
URIEncoding=”GBK”
完整的应如下:
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/>
2)重启tomcat,一切OK。
需要加入的原因大家可以去研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的这个文件就可以知道原因了。需要注意的是:这个地方如果你要是用UTF-8的时候在传递的过程中在Tomcat中也是要出现乱码的情况,如果不行的话就换别的字符集。
(四)    JSP页面上有中文,按钮上面也有中文,但是通过服务器查看页面的时候出现乱码:
     解决的办法是:首先在JSP文件中不应该直接包含本地化的消息文本,而是应该通过<bean:message>标签从Resource Bundle中获得文本。应该把你的中文文本放到Application.properties文件中,这个文件放在WEB-INF/classes/*下,例如我在页面里有姓名,年龄两个label,我首先就是要建一个Application.properties,里面的内容应该是name=”姓名” age=”年龄”,然后我把这个文件放到WEB-INF/classes/properties/下,接下来根据Application.properties文件,对他进行编码转化,创建一个中文资源文件,假定名字是Application_cn.properties。在JDK中提供了native2ascii命令,他能够实现字符编码的转换。在DOS环境中找到你放置Application.properties的这个文件的目录,在DOS环境中执行一下命令,将生成按GBK编码的中文资源文件Application_cn.properties:native2ascii ?encoding gbk Application.properties Application_cn.properties执行以上命令以后将生成如下内容的Application_cn.properties文件:name=\u59d3\u540d age=\u5e74\u9f84,在Struts-config.xml中配置:<message-resources parameter="properties.Application_cn"/>。到这一步,基本上完成了一大半,接着你就要在JSP页面上写<%@ page language="java" contentType="text/html;charset=GBK" %>,到名字的那个label是要写<bean:message key=”name”>,这样的化在页面上出现的时候就会出现中文的姓名,年龄这个也是一样,按钮上汉字的处理也是同样的。
(五)    写入到数据库是乱码:
解决的方法:要配置一个filter,也就是一个Servelet的过滤器,代码如同第二种时候一样。
如果你是通过JDBC直接链接数据库的时候,配置的代码如下:jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK,这样保证到数据库中的代码是不是乱码。
如果你是通过数据源链接的化你不能按照这样的写法了,首先你就要写在配置文件中,在tomcat 5.0.19中配置数据源的地方是在C:\Tomcat 5.0\conf\Catalina\localhost这个下面,我建立的工程是workshop,放置的目录是webapp下面,workshop.xml的配置文件如下:
<!-- insert this Context element into server.xml -->
<Context path="/workshop" docBase="workshop" debug="0"
reloadable="true" >
  <Resource name="jdbc/WorkshopDB"
               auth="Container"
               type="javax.sql.DataSource" />
  <ResourceParams name="jdbc/WorkshopDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>
    <parameter>
      <name>

maxActive</name>
      <value>100</value>
    </parameter>
    <parameter>
      <name>maxIdle</name>
      <value>30</value>
    </parameter>
   
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>
      <parameter>
     <name>username</name>
     <value>root</value>
    </parameter>
    <parameter>
     <name>password</name>
     <value></value>
    </parameter>
    <!-- Class name for mm.mysql JDBC driver -->
    <parameter>
       <name>driverClassName</name>
       <value>com.mysql.jdbc.Driver</value>
</parameter>
   <parameter>
      <name>url</name>
 <value><![CDATA[jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK]]></value>
    </parameter>
  </ResourceParams>
</Context>
粗体的地方要特别的注意,和JDBC直接链接的时候是有区别的,如果你是配置正确的化,当你输入中文的时候到数据库中就是中文了,有一点要注意的是你在显示数据的页面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>这行代码的。需要注意的是有的前台的人员在写代码的是后用Dreamver写的,写了一个Form的时候把他改成了一个jsp,这样有一个地方要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他该过来,因为在jsp的提交的过程中紧紧就是POST和GET两种方式,但是这两种方式提交的代码在编码方面还是有很大不同的,这个在后面的地方进行说明.


文章出处:http://www.diybl.com/course/3_program/java/javajs/200829/99730_3.html

posted @ 2008-12-15 17:09 wesley1987 阅读(465) | 评论 (0)编辑 收藏