oracle的字符集是WE8ISO8859P1,由于历史原因,不可修改。已经修改本地
NLS_LANG,因此使用PL/SQL developer可以正常访问。
但是 hibernate使用thin方式连接数据库,中文乱码。
为了使页面可以正常显示,在取数据时在form的get方法中使用
String new_str = new String(old_str.getBytes("iso-8859-1"));
得到的new_str可以正常显示中文。
但是这样增加了冗余代码,而且使用好多第三方组件时,由于无法控制转码细节,导致乱码。
在互联网上搜索解决方案,搜到的大多是一个方法,加入filter,使用org.springframework.web.filter.CharacterEncodingFilter
但是对我这个情况完全无效,存取数据都是乱码,存到数据库里的数用客户端看也是乱码。
我觉得CharacterEncodingFilter应该是在oracle的字符集正确设置的情况下,比如使用ZHS16GBK,解决乱码的问题。
现在请教各位高手有没有遇到过同样的问题,如何解决这种情况下的乱码。是否需要写一个filter或者是hibernate直接可以对oracle字符集进行配置。

解决方案 »

  1.   

    Oracle论坛里似乎有一个问题和你的提问一模一样:
    http://forums.oracle.com/forums/thread.jspa?messageID=1693980不过结论似乎比较悲观,因为Oracle的jdbc驱动,似乎不像mysql那样,支持字符集参数。但似乎有一个人回复说,可以通过设置NLS_LANG参数来影响jdbc的转换:
    Re: Is it possible to set JDBC Driver CharacterSet 
    Posted: 2007-2-15 下午3:10    in response to: user540677         Reply  
     
    As far as I know, basic conversion handling is done in layers.OCI (thick) JDBC, from database to app:
    db <-> oci (like regular oci apps) <-> jdbc (for a few char sets, directly to java) <-> java (ucs2-like encoding).Thin JDBC:
    db <-> jdbc (from server in utf-8) <-> javaBy using NLS_LANG you can indicate which character set (encoding) you want Oracle to convert to, at the OCI level. JDBC will ignore it (10g) or use it for internal conversion only (pre 10g).That's how I see it, not sure if it helps Message was edited by: 
    orafad 
     
    希望有所帮助!
      

  2.   

    转码  String new_str = new String(old_str.getBytes("iso-8859-1"));  这样好行不对类。String里面应该有两种编码
      

  3.   

    package com.xicai.util; 如果你用的是三大框架,下面可以帮你
    第一步:在你的项目中加上如下类MyRequestProcessor 
    import java.io.UnsupportedEncodingException;import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;import org.apache.struts.action.RequestProcessor;public class MyRequestProcessor extends RequestProcessor {
     protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) {
      try {
       request.setCharacterEncoding("gb2312");
      } catch (UnsupportedEncodingException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      return super.processPreprocess(request, response);
     } 
    }
    第二步:在你的strut-config.xml中加入以下节点
    <controller  processorClass="com.xicai.util.MyRequestProcessor"></controller>
      

  4.   

    httprequest的charset和数据库中的值有什么关系?
    设了这个真的有效吗?
      

  5.   

    问题已经解决,说一下我的解决方案吧。使用hibernate的UserType 在hbm.xml中配置,比如
            <property name="roleName" type="com.xtmcc.framework.dao.GBKString">
                <column name="ROLE_NAME" length="50" />
            </property>
    自定义GBKString 类
    package com.xtmcc.framework.dao;import java.io.Serializable;   
    import java.io.UnsupportedEncodingException;   
    import java.sql.PreparedStatement;   
    import java.sql.ResultSet;   
    import java.sql.SQLException;   
      
    import oracle.jdbc.driver.OracleTypes;   
      
    import org.apache.commons.lang.builder.HashCodeBuilder;   
    import org.hibernate.HibernateException;   
    import org.hibernate.usertype.UserType;   public class GBKString implements UserType {   
      
        public GBKString() {   
            super();   
        }   
      
        public int[] sqlTypes() {   
            return new int[] { OracleTypes.VARCHAR };   
        }   
      
        public Class returnedClass() {   
            return String.class;   
        }   
      
        public boolean equals(Object x, Object y) throws HibernateException {   
            return (x == y) || (x != null && y != null && (x.equals(y)));   
        }   
      
        public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException,   
                SQLException {   
            String val = rs.getString(names[0]);   
            if (null == val) {   
                return null;   
            } else {   
                try {   
                    val = new String(val.getBytes("iso-8859-1"), "GBK");   
                } catch (UnsupportedEncodingException e) {   
                    throw new HibernateException(e.getMessage());   
                }   
                return val;   
            }   
        }   
      
        public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException,   
                SQLException {   
            if (value == null) {   
                st.setNull(index, OracleTypes.VARCHAR);   
            } else {   
                String val = (String)value;   
                try {   
                 val = new String(val.getBytes("GBK"), "ISO_8859_1");  
                } catch (UnsupportedEncodingException e) {   
                    throw new HibernateException(e.getMessage());   
                }   
                st.setObject(index, val, OracleTypes.VARCHAR);   
            }   
        }   
        public Object deepCopy(Object value) throws HibernateException {   
            if (value == null)   
                return null;   
            return new String((String) value);   
        }   
      
        public boolean isMutable() {   
            return false;   
        }   
      
        public Object assemble(Serializable arg0, Object arg1) throws HibernateException {   
            // TODO Auto-generated method stub   
            return null;   
        }   
      
        public Serializable disassemble(Object arg0) throws HibernateException {   
            // TODO Auto-generated method stub   
            return null;   
        }   
      
        public int hashCode(Object arg0) throws HibernateException {   
            return HashCodeBuilder.reflectionHashCode(this);   
        }   
      
        public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {   
            // TODO Auto-generated method stub   
            return null;   
        }   }
      

  6.   


    LZ试试:
    String newStr = new String(oldStr.getBytes("iso8859-1"), "GBK");