﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-张春利-文章分类-struts</title><link>http://www.blogjava.net/zcljob/category/10184.html</link><description>张春利</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:57:21 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:57:21 GMT</pubDate><ttl>60</ttl><item><title>利用filter实现MVC应用框架 及 网页编码问题的解决方案</title><link>http://www.blogjava.net/zcljob/articles/45218.html</link><dc:creator>张春利</dc:creator><author>张春利</author><pubDate>Tue, 09 May 2006 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/zcljob/articles/45218.html</guid><wfw:comment>http://www.blogjava.net/zcljob/comments/45218.html</wfw:comment><comments>http://www.blogjava.net/zcljob/articles/45218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zcljob/comments/commentRss/45218.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zcljob/services/trackbacks/45218.html</trackback:ping><description><![CDATA[
		<h3 align="center">
				<font size="5">
				</font> </h3>
		<pre>
				<font size="5">MVC（Model-View-Controller）是java网页应用的一种实现框架。亦即model-2。
其主要思想是：统一的controller（一个或一组servlet）来处理request和response，
然后决定和构造（通常利用jsp模板）显示给用户的界面（view），同时使用处理特定事务的共享的bean/EJB(model)。
Struts就是MVC框架的一个实例。

可是要使用这些框架，势必要花时间学习它们、同时局限于它们的实现机制。

servlet规范（ specification ）version 2.3 增加了一个新的机制：filter。其定义参见规范第6章。
凡是宣称支持servlet 2.3的web服务器都应支持filter机制。
利用filter，可以非常简便地实现自己的MVC。

简单地说，filter就是在调用web应用的若干或全部的动态内容（servlet/jsp）和静态内容（html/）之前，
由servlet包容器自动调用的代码。
filter是web应用程序的一部分、 由开发者自己编写和发布。

--------- 以下内容整理自servlet specification version 2.3

filter可以实现以下功能：(动态和静态内容合称为“web资源”)
    * 在调用request之前，访问request需要的一个资源。
    * 在一个资源调用request之前，处理request。
    * 修改request的头信息和数据，将request封装成定制的request版本。
    * 修改response的头文件和数据，提供定制的response版本。
    * 拦截对一个资源的调用。
    * 以特定的顺序，零个、一个、或多个filter,作用于一个servlet、一组servlet或静态内容上。

filter的例子包括：
    * 认证filter
    * 日志和审计filter
    * 图片转换fiter
    * 数据压缩 filter
    * 加密 filter
    * 标记（Tokenizing） filter
    * 触发资源访问事件的 filter
    * 转换XML内容的XSL/T filter
    * MIME-type 链 filter
    * 缓存 filter

----------- 更多内容有劳其他/她好事者翻译吧


以下是本人实现和发布的一个character encoding filter的内容。
1）作用：统一设置所有servlet的编码方式。
2）好处：
    （1）所有servlet都不需要包含设置编码方式的代码。
    （2）可以统一管理/修改所有servlet的编码方式。
3）发布此filter。在“应用程序目录/web/WEB-INF/web.xml”的最前面（<web-app>下一行）添加：

-----------------在<web-app>下一行添加的内容-----------------

</web-app></web-app></font>
				<a href="http://www.chong2.com/yue/sujiu/java_filterusemvc.txt" target="_blank">
						<font size="5">添加的内容</font>
				</a>
				<font size="5">4）此filter的代码如下：(注意，所有servlet中就不要设置request和response的编码了)

-----------filter的代码，已包含javadoc格式，写得很规范呐 （得意中...）----------

/*
* FileName:        CharacterEncodingFilter.java       
*
* Last Updated:    2002-4-19
*
* Writer:        Mara Ren
*
*/

package see.common.filters;

import java.io.IOException;
import javax.servlet.*;


/**
* This filter sets the character encoding to be used for current
* request and response.
*
* The value is set according the following order:
* </font>
				<li>
						<font size="5">Current user's configuration, if the user has registered
* </font>
				</li>
				<li>
						<font size="5">The character encoding used in the body of current request
* </font>
				</li>
				<li>
						<font size="5">The default character encoding in application's configuration
*
* @version     2002-4-19
* @author     Mara Ren
*/


public class CharacterEncodingFilter
             implements Filter {


    // --------------------- Instance Variables -----------------

    /**
     * The character encoding to set be used for current request 
     * and response
     */
    private String encoding = null;


    /**
     * The filter configuration object we are associated with.  If this value
     * is null, this filter instance is not currently configured.
     */
    protected FilterConfig filterConfig = null;


    // ------------ Public Methods (standard, overrided) ---------


    /**
     * Place this filter into service.
     *
     * @param filterConfig The filter configuration object
     */

    public void init(FilterConfig filterConfig)
                throws ServletException {

        this.filterConfig = filterConfig;

    }


    /**
     * This filter sets the character encoding to be used for current
     * request and response.
     *
     * @param request The servlet request we are processing
     * @param result The servlet response we are creating
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */

    public void doFilter(ServletRequest  request, 
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException {

        encoding = getUserEncoding(); //当前用户的编码方式，是用户配置的一个值

        if (encoding == null)
        {
            encoding = request.getCharacterEncoding(); // 浏览器返回的编码方式
        }

        if (encoding == null)
        {
            encoding = filterConfig.getInitParameter("encoding"); //应用程序的编码方式
        }

        if (encoding != null)
        {
            request.setCharacterEncoding(encoding); //这是servlet 2.3新加的方法，专门在设置request编码方式
            response.setContentType("text/html;charset=" + encoding); //设置response编码方式
        }

    // Pass control on to the next filter
        chain.doFilter(request, response);

    }



    /**
     * Take this filter out of service.
     */
    public void destroy() {

        this.encoding = null;
        this.filterConfig = null;

    }


    /**
     * Get encoding from current user's configuration.
     */

    private String getUserEncoding() {
    
        // 从当前用户的session或配置文件中读取，自己编写吧
    }


}


------------------------------------------------------


再罗嗦一句，看到很多朋友在为网页编码问题苦恼，不禁要问一句：
    你们搞清楚request编码和response编码的区别了吗？
不要认为在response中设置了gb2312，就能直接按gb2312来访问request的数据。

request是浏览器返回给服务器、服务器处理后提供给你的。
request的编码取决于非常多的因素：
1）浏览器可以不返回编码方式，也可以返回约定的缺省编码（iso8859-1），也可以按客户端的当前
设置（例如你的IE被你设为gb2312）。它可不是按照你提供的response的编码方式来返回request的!
2）如果浏览器不告诉服务器request编码方式，服务器可以按照约定的编码方式（iso8859-1）来为你
提供request（这是servlet规范要求的，是最简洁最正确的解决办法），也可以好事地为你猜测客户端
的设置或服务器端的设置而编码request（其实这样做是非常危险的，本人认为不可取！）。
3）有些java编程平台也会为你设置或猜测request的编码方式（如果你要真正发布一个应用，这个问题
最好不要依赖于编程平台！）
4）开发者可以设置服务器用来解释和提供request的编码方式。

所以很多人往往不处理request编码、就访问request数据（大家倒是总记得处理reponse编码），要么
运行结果乱七八糟，要么只能在特定情况下才能正确显示。

处理request编码的一个方案是：（不干预服务器解释和提供request的编码方式）
1）判断服务器是按什么编码方式来提供和解释request的
2）如果不是你要的编码方式，将request数据转换你要的编码方式，然后再按你的编码方式来使用request数据。

以上filter其实是解决request编码的另一个方案：（干预服务器解释和提供request的编码方式）
1）按照servlet 2.3定义，用户可以用request.setCharacterEncoding(encoding)方法来要求服务器
按你要求的编码方式来解释和提供request。
2）不必转换request编码方式、就可以直接按你的编码方式来使用request数据了。

可以看到，其实还是后一种方案更简洁（不必转换编码了）。

不知道你是否理解这番解释？真是希望更多的人不再为网页编码问题浪费时间了。
</font>
				</li>
		</pre>
<img src ="http://www.blogjava.net/zcljob/aggbug/45218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zcljob/" target="_blank">张春利</a> 2006-05-09 15:21 <a href="http://www.blogjava.net/zcljob/articles/45218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>