在做网站开发项目过程中,我们一定会遇到网站的中文乱码问题,如何解决中文乱码为题成为我们开发网站的一个关键问题,也许解决乱码问题很简单,只要通过response和request中的setCharater()方法就可以解决乱码问题,也许这种方法我们在买的教科书书上会看到特别多,然而我们一旦开发网站项目随着深入开发和业务的深入,如果每次在每个servlet或者jsp这样设置或变得非常冗余,而且也完全没必要这样设置,那么我们就会想用什么样的方法来解决这样问题呢,当然java web中有种很好的解决方法,那就是通过实现过滤器Filter接口可以很好的解决我们整个网站的乱码,不管是get请求或者post请求,在这个解决中文乱码的过滤器中都会乖乖现出他的本质。那么接下来,就贴出我在学习java web过程中和做网站项目中经常用到的解决中文乱码过滤器(CharacterEncodingFilter):
过滤器如下:
package com.test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class CharacterEncodingFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) res;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(new FilterRequest(request), response);
}
class FilterRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public FilterRequest(HttpServletRequest request) {
super(request);
// TODO Auto-generated constructor stub
this.request=request;
}
public String getParameter(String name) {
// TODO Auto-generated method stub
String value=this.request.getParameter(name);
/*如果不是get方式提交,那么是post提交(我们一般都是这两种方式提交,当然还有其他很少用的提交方式)
由于上面已经对post提交方式进行了编码,所以则直接提交*/
if(!this.request.getMethod().equalsIgnoreCase("get")){//忽略大小写字母,字符串内容相等
return value;
}
if(value==null){
return null;
}
try {
value=new String(value.getBytes("iso8859-1"),request.getCharacterEncoding());
return value;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
}
同时我们要在web.xml配置过滤:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.test.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 拦截所有请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
接下来让我们用ajax实现省级联动并且用到上面的过滤器,由于我这个例子没有用到数据库,只是通过在程序固定写死了相关的数据,所以我在下面程序中着重的讲的是如何ajax联动,如果要跟数据库相关联,只需把相关的代码改一下就可以实现了。
第一步:写一个javaBean记录相关省市信息.
ProvinceAndCityBean:
package com.test;
import java.util.HashMap;
import java.util.Map;
public class ProvinceAndCityBean {
private static Map<String,String[]> map;
/**
* 静态代码块在类加载的时候初始化一次数据
*/
static{
map=new HashMap<String, String[]>();
map.put("广东",new String[]{"广州","深圳","东莞","中山", "珠海", "佛山", "汕尾"} );
map.put("福建",new String[]{"厦门", "福州", "泉州"} );
map.put("广西",new String[]{ "桂林", "南宁", "柳州", "梧州"});
}
public static Map<String,String[]> getMap(){
return map;
}
}
第二步:我们写一个servlet来处理jsp页面的请求,从而获得省份以及根据省份获得市的信息,接下来写一个处理请求的servlet.
AjaxServlet:
package com.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AjaxServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action= request.getParameter("action");
if("getProvince".equals(action)){
getProvince(request,response);
}else if("getCity".equals(action)){
getCity(request,response);
}
}
/**
* 根据省份获得城市
* @param request
* @param response
*/
private void getCity(HttpServletRequest request,HttpServletResponse response) {
// TODO Auto-generated method stub
String cityResult="";
String selectProvince=request.getParameter("selectProvince");
Map<String,String[]> map=ProvinceAndCityBean.getMap();
String[] cityArray=map.get(selectProvince);
for(int i=0;i<cityArray.length;i++){
cityResult=cityResult+cityArray[i]+",";
}
cityResult=cityResult.substring(0,cityResult.length()-1);
PrintWriter out=null;
try{
out=response.getWriter();
out.write(cityResult);
out.flush();
out.close();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* 获得省份数据
* @param request
* @param response
*/
private void getProvince(HttpServletRequest request,HttpServletResponse response) {
// TODO Auto-generated method stub
Map<String,String[]> map=ProvinceAndCityBean.getMap();//获得存储省份市的map集合
Set<String> set= map.keySet();
String provinceResult="";
System.out.println(map.size());
for(String pro:set){
provinceResult=provinceResult+pro+",";//拼写以,分隔省份字符串广东,福建,广西
}
provinceResult=provinceResult.substring(0, provinceResult.length()-1);
PrintWriter writer;
try {
writer = response.getWriter();
writer.write(provinceResult);
writer.flush();
System.out.println(provinceResult);
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
最后一步写一个jsp页面,由于页面中用到ajax中,所以学习ajax相关度的知识可以到
w3school学习,我也是在w3school学习的,接下来贴出我的代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>省市联动查询</title>
<script type="text/javascript">
var xmlhttp;
/*
*创建一个异步请求对象
*/
function createXmlHttp(){
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
/*
初始化省份
*/
var selPro;
function initSelPro(){
createXmlHttp();
selPro=document.getElementById("selPro");//获得省份select标签节点
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4&&xmlhttp.status==200){
var provinceArray=xmlhttp.responseText.split(",");
for(i=0;i<provinceArray.length;i++){
selPro.options[i]=new Option(provinceArray[i],provinceArray[i]);
}
getCityByPro('广东');
}
};
//以get的方式请求,new Date().getTime()是为防止加载浏览器中的缓存数据
xmlhttp.open("GET","${pageContext.request.contextPath}/AjaxServlet?action=getProvince&id="+new Date().getTime() ,true);
xmlhttp.send();
}
/*
根据省份查询市,下面是通过post方式实现,当然也可以通过get方式实现,跟上面的实现一样
*/
function getCityByPro(selectProvince){
var selCity=document.getElementById("selCity");
selCity.options.length=0;//清空下拉列表
xmlhttp.open("POST", "AjaxServlet", true);
xmlhttp.setRequestHeader("content-type", "application/x-www-form-urlencoded");
var content="action=getCity&selectProvince="+selectProvince;
xmlhttp.send(content);
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4&&xmlhttp.status==200){
var cityArray=xmlhttp.responseText.split(",");
for(i=0;i<cityArray.length;i++){
selCity.options[i]=new Option(cityArray[i],cityArray[i]);
}
}
};
}
/*
页面加载的时候初始化省份
*/
window.οnlοad=function(){
initSelPro();
}
</script>
</head>
<body>
省级联动菜单事例:
<select name="selPro" id="selPro" οnchange="getCityByPro(this.value)">
</select>
<select name="selCity" id="selCity" >
</select>
</body>
</html>
接下来看看效果吧:
页面刚加载的时候的效果: