`
dy3168729
  • 浏览: 39599 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

bean:include 乱码:struts1 使用bean:include 中文乱码问题 优雅解决

    博客分类:
  • J2EE
阅读更多
/*
 * $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.struts.taglib.bean;

import org.apache.struts.taglib.TagUtils;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import java.io.BufferedInputStream;
import java.io.InputStreamReader;

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import java.util.Map;

/**
 * Define the contents of a specified intra-application request as a page
 * scope attribute of type <code>java.lang.String</code>.  If the current
 * request is part of a session, the session identifier will be included in
 * the generated request, so it will be part of the same session. <p>
 * <strong>FIXME</strong>:  In a servlet 2.3 environment, we can use a wrapped
 * response passed to RequestDispatcher.include().
 *
 * @version $Rev$ $Date: 2005-08-21 19:08:45 -0400 (Sun, 21 Aug 2005)
 *          $
 */
public class IncludeTag extends TagSupport {
    // ------------------------------------------------------------- Properties

    /**
     * Buffer size to use when reading the input stream.
     */
    protected static final int BUFFER_SIZE = 256;

    /**
     * The message resources for this package.
     */
    protected static MessageResources messages =
        MessageResources.getMessageResources(
            "org.apache.struts.taglib.bean.LocalStrings");

    /**
     * The anchor to be added to the end of the generated hyperlink.
     */
    protected String anchor = null;

    /**
     * The name of the global <code>ActionForward</code> that contains a path
     * to our requested resource.
     */
    protected String forward = null;

    /**
     * The absolute URL to the resource to be included.
     */
    protected String href = null;

    /**
     * The name of the scripting variable that will be exposed as a page scope
     * attribute.
     */
    protected String id = null;

    /**
     * The context-relative URI of the page or servlet to be included.
     */
    protected String page = null;

    /**
     * Include transaction token (if any) in the hyperlink?
     */
    protected boolean transaction = false;
    protected boolean useLocalEncoding = false;
	
    protected String useEncodingName = null;


	
    public String getAnchor() {
        return (this.anchor);
    }

    public void setAnchor(String anchor) {
        this.anchor = anchor;
    }

    public String getForward() {
        return (this.forward);
    }

    public void setForward(String forward) {
        this.forward = forward;
    }

    public String getHref() {
        return (this.href);
    }

    public void setHref(String href) {
        this.href = href;
    }

    public String getId() {
        return (this.id);
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPage() {
        return (this.page);
    }

    public void setPage(String page) {
        this.page = page;
    }

    public boolean getTransaction() {
        return (this.transaction);
    }

    public void setTransaction(boolean transaction) {
        this.transaction = transaction;
    }

    public boolean isUseLocalEncoding() {
        return useLocalEncoding;
    }

    public void setUseLocalEncoding(boolean b) {
        useLocalEncoding = b;
    }
	
	public String getUseEncodingName() {
	    return (this.useEncodingName);
	}
	public void setUseEncodingName(String useEncodingName) {
		this.useEncodingName = useEncodingName;
	}

    // --------------------------------------------------------- Public Methods

    /**
     * Define the contents returned for the specified resource as a page scope
     * attribute.
     *
     * @throws javax.servlet.jsp.JspException if a JSP error occurs
     */
    public int doStartTag() throws JspException {
        // Set up a URLConnection to read the requested resource
        Map params =
            TagUtils.getInstance().computeParameters(pageContext, null, null,
                null, null, null, null, null, transaction);

        // FIXME - <html:link> attributes
        String urlString = null;
        URL url = null;

        try {
            urlString =
                TagUtils.getInstance().computeURLWithCharEncoding(pageContext,
                    forward, href, page, null, null, params, anchor, false,
                    useLocalEncoding);

            if (urlString.indexOf(':') < 0) {
                HttpServletRequest request =
                    (HttpServletRequest) pageContext.getRequest();

                url = new URL(RequestUtils.requestURL(request), urlString);
            } else {
                url = new URL(urlString);
            }
        } catch (MalformedURLException e) {
            TagUtils.getInstance().saveException(pageContext, e);
            throw new JspException(messages.getMessage("include.url",
                    e.toString()), e);
        }

        URLConnection conn = null;

        try {
            // Set up the basic connection
            conn = url.openConnection();
            conn.setAllowUserInteraction(false);
            conn.setDoInput(true);
            conn.setDoOutput(false);

            // Add a session id cookie if appropriate
            HttpServletRequest request =
                (HttpServletRequest) pageContext.getRequest();

            addCookie(conn, urlString, request);

            // Connect to the requested resource
            conn.connect();
        } catch (Exception e) {
            TagUtils.getInstance().saveException(pageContext, e);
            throw new JspException(messages.getMessage("include.open",
                    url.toString(), e.toString()), e);
        }

        // Copy the contents of this URL
        StringBuffer sb = new StringBuffer();

        try {
            BufferedInputStream is =
                new BufferedInputStream(conn.getInputStream());
	   //编码乱码问题的根源	
            InputStreamReader in = new InputStreamReader(is,useEncodingName); // FIXME- encodin
            char[] buffer = new char[BUFFER_SIZE];
            int n = 0;

            while (true) {
                n = in.read(buffer);

                if (n < 1) {
                    break;
                }

                sb.append(buffer, 0, n);
            }

            in.close();
        } catch (Exception e) {
            TagUtils.getInstance().saveException(pageContext, e);
            throw new JspException(messages.getMessage("include.read",
                    url.toString(), e.toString()), e);
        }

        // Define the retrieved content as a page scope attribute
        pageContext.setAttribute(id, sb.toString());

        // Skip any body of this tag
        return (SKIP_BODY);
    }

    /**
     * Add a session id cookie if appropriate. Can be overloaded to support a
     * cluster.
     *
     * @param conn
     * @param urlString
     * @param request
     * @since Struts 1.2.0
     */
    protected void addCookie(URLConnection conn, String urlString,
        HttpServletRequest request) {
        if ((conn instanceof HttpURLConnection)
            && urlString.startsWith(request.getContextPath())
            && (request.getRequestedSessionId() != null)
            && request.isRequestedSessionIdFromCookie()) {
            StringBuffer sb = new StringBuffer("JSESSIONID=");

            sb.append(request.getRequestedSessionId());
            conn.setRequestProperty("Cookie", sb.toString());
        }
    }

    /**
     * Release all allocated resources.
     */
    public void release() {
        super.release();
        anchor = null;
        forward = null;
        href = null;
        id = null;
        page = null;
        transaction = false;
    }
}

   大家可以看这个类的struts1 源码第234行,源代码上

  InputStreamReader in = new InputStreamReader(is);//FIXME- encoding

默认写法是这样的(上面都写了fixme-encoding,我就想不通怎么没有修正),如果没有指定编码,将使用平台的默认编码

所以添加     protected String useEncodingName = null; 及其get set方法

传入我们额外增加的变量 ,InputStreamReader in = new InputStreamReader(is,useEncodingName);

完成修改之后,本地编译,然后将生成的class文件覆盖struts.jar中的原有IncludeTag.class,为了保险起见,请注意覆盖前请先备份

 

<tag>
<name>include</name>
<tagclass>org.apache.struts.taglib.bean.IncludeTag</tagclass>
<teiclass>org.apache.struts.taglib.bean.IncludeTei</teiclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>anchor</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>forward</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>href</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>page</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>transaction</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>useEncodingName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

  修改struts-bean.tld  添加

<attribute>
<name>useEncodingName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
这几行定义

 

<%
    if(StringUtils.isNotEmpty(zj_sjd_id)){
        String page_url = "/bgSjdMgr.do?method=showBgShouyDetail&sjdid="+ zj_sjd_id;
%>
<bean:include id="showBgShouyDetail" page="<%=page_url%>" useEncodingName="utf-8"/>
<bean:write name="showBgShouyDetail" filter="false"/>
<%
    }
%>

   在调用的时候,补上目标页面使用的编码格式,如上,我的原页面和目标页面都是utf-8,问题解决。

我开始搜这个问题的时候,网上所说的使用目标页面编码改成gbk的不优雅解决方式其实就是和默认的平台编码匹配。

本人的愚见 欢迎各路同行不吝赐教,共同探讨

 

 

分享到:
评论

相关推荐

    struts2+kindEditor4.1.7

    中文乱码不是问题,一般struts2+spring开发项目的时候,使用spring的filter就可以搞定 &lt;filter-name&gt;Set Character Encoding &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter ...

    java web技术开发大全(最全最新)

    4.7.3 实例:解决服务端程序读取中文请求消息的乱码问题 4.7.4 实例:用AJAX技术发送和接收中文信息 4.7.5 实例:在请求消息头和响应消息头中转输中文 4.8 小结 第5章 JSP技术 5.1 用MyEclipse编写第一个...

    java web开发技术大全

    4.7.3 实例:解决服务端程序读取中文请求消息的乱码问题 4.7.4 实例:用AJAX技术发送和接收中文信息 4.7.5 实例:在请求消息头和响应消息头中转输中文 4.8 小结 第5章 JSP技术 5.1 用MyEclipse编写第...

    java web 视频、电子书、源码(李兴华老师出版)

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1...

    李兴华Java Web开发实战经典.pdf (高清版) Part1

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1...

    李兴华 Java Web 开发实战经典_带源码_高清pdf 带书签 上

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1、取得...

    MLDN+李兴华+Java+Web开发实战经典.part3.rar )

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1...

    李兴华 java_web开发实战经典 源码 完整版收集共享

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1、取得...

    李兴华 Java Web 开发实战经典_带源码_高清pdf 带书签 下

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1、取得...

    李兴华 Java Web 开发实战经典 高清扫描版Part3

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1、取得...

    李兴华Java Web开发实战经典(高清版) Part2

    6.3.1、乱码解决 6.3.2、接收请求参数 6.3.3、显示全部的头信息 6.3.4、角色验证 6.3.5、其他操作 6.4、response对象 6.4.1、设置头信息 6.4.2、页面跳转 6.4.3、操作Cookie 6.5、session对象 6.5.1...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    3.4.2 解决中文乱码 3.4.3 获取客户端数据 3.5 response回应对象的应用 3.5.1 HTTP头信息的操作 3.5.2 设置MIME类型 3.5 13页面重定向操作 3.6 Session会话对象的应用 3.6.1 session的生命周期 3.6.2 会话的创建与...

Global site tag (gtag.js) - Google Analytics