在做网站开发项目过程中,我们一定会遇到网站的中文乱码问题,如何解决中文乱码为题成为我们开发网站的一个关键问题,也许解决乱码问题很简单,只要通过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,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.onload=function(){ initSelPro(); } </script> </head> <body> 省级联动菜单事例: <select name="selPro" id="selPro" onchange="getCityByPro(this.value)"> </select> <select name="selCity" id="selCity" > </select> </body> </html>
接下来看看效果吧: