解决JSF + Spring2.0 + Hibernate3.2 + MySQL 乱码问题

本文介绍如何解决JavaWeb应用中的中文乱码问题,包括设置页面编码、使用过滤器处理请求编码及调整数据库连接参数。

在公司做的项目一般都是英文的,也就是默认的拉丁字符集 ISO-8859-1。在今天做的J+S+H应用中,我想插入保存一个中文的用户名,可是不管怎么样保存,都是问号形式的乱码。

 

乱码问题一直是个比较头疼而又常见的问题,困扰着我们这些实用Unicode的群众。在Java Web应用中,乱码一般会出现在页面JSP显示层或者数据库持久层。对于前者,我们一般是注意在页面的头部代码中加入

<%@page contentType="text/html;charset=GB2312"%>  

或者

<%@page contentType="text/html"%>  
<%@page pageEncoding="UTF-8"%>  

 

如果依旧不行,考虑到对request中的数据进行一个ISO-8859到Unicode字符集的转换过程,一般都是通过一个Filter来实现,如下面的样例代码:

package com.array.dinner.utils;   
  
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;   
  
public class SetCharacterEncoding implements Filter {   
    protected String encoding = null;   
  
    protected FilterConfig filterConfig = null;   
  
    protected boolean ignore = true;   
  
    public void destroy() {   
        this.encoding = null;   
        this.filterConfig = null;   
    }   
  
    public void doFilter(ServletRequest request, ServletResponse response,   
            FilterChain chain) throws IOException, ServletException {   
        // Conditionally select and set the character encoding to be used   
        if (ignore || (request.getCharacterEncoding() == null)) {   
            String encoding = selectEncoding(request);   
            if (encoding != null)   
                request.setCharacterEncoding(encoding);   
        }   
        // Pass control on to the next filter   
        chain.doFilter(request, response);   
    }   
  
    public void init(FilterConfig filterConfig) throws ServletException {   
        this.filterConfig = filterConfig;   
        this.encoding = filterConfig.getInitParameter("encoding");   
        String value = filterConfig.getInitParameter("ignore");   
        if (value == null)   
            this.ignore = true;   
        else if (value.equalsIgnoreCase("true"))   
            this.ignore = true;   
        else if (value.equalsIgnoreCase("yes"))   
            this.ignore = true;   
        else  
            this.ignore = false;   
    }   
  
    protected String selectEncoding(ServletRequest request) {   
        return (this.encoding);   
    }   
}  

 

对应的web.xml的配置应该添加一下Filter声明:

<filter>  
      <filter-name>setCharacterEncoding</filter-name>  
      <filter-class>com.array.dinner.utils.SetCharacterEncodingFilter</filter-class>  
      <init-param>  
            <param-name>encoding</param-name>  
            <param-value>gb2312</param-value>  
      </init-param>  
</filter>  
<filter-mapping>  
       <filter-name>setCharacterEncoding</filter-name>  
       <url-pattern>/*</url-pattern>  
</filter-mapping>

 

但是,当我跟踪到JSF的后台bean中,又能完整地看到变量的完整地中文字符。很明显,是在数据库的持久层上出问题了。仔细检查一下了自己的MySQL数据库,发现所有的表都是建立在UTF-8之上的,数据库本身应该是没有问题的。

 

顺着想一想,结论马上就浮出水面了,我输入的是中文字符GBK的,而数据库接受的却是UTF-8,数据库方面默认用UTF-8来处理和保存一堆传过来的Unicode字符,但是数据库方面是不知道对方来的数据是什么编码的,所以只能用问号表示“抗议”。所以,这里只需要让数据库了解你的数据包的性质,沟通自然就无问题了。废话少说,你只需要在数据库连接url中这样声明一下,多加两个参数useUnicode和characterEncoding:

jdbc:mysql://localhost:3306/dinner?useUnicode=true&characterEncoding=UTF-8

(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值