(WEB学习笔记 一)
(如何解决向客户端输出中文数据乱码问题,分别以OutputStream和PrintWriter输出
)
有两种方式解决向客户端输出中文数据乱码问题:如代码中 test1(); 和 test2(); 方法所示
public class ResponseDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
test2(response);
}
//方式一: 解决乱码问题,保证输出编码和浏览器的编码保持一致
public void test1(HttpServletResponse response) throws IOException{
String data ="中国";
OutputStream out = response.getOutputStream();
// 程序以码表输出 ,一定要控制输出的格式相同.控制浏览器输出同样的格式
response.setHeader("Content-type", "text/html;charset=gbk");
// out.write(data.getBytes()); //可能这样输出的就是乱码
//out.write(data.getBytes("UTF-8")); //乱码
//out.write(data.getBytes("GB2312"));
out.write(data.getBytes("GBK"));
}
//方式二:模拟一个http相应头
public void test2(HttpServletResponse response) throws IOException{
String data ="中国2";
//模拟一个html:标签 (类似于index.jsp里面的)模拟http响应头
OutputStream out = response.getOutputStream();
out.write("".getBytes());
out.write(data.getBytes("gbk"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
三种方式解决:如下代码,使用时采用其中一种方式即可
private void test1(HttpServletResponse response) throws IOException {
String data = "中国";
// 设置 Response相应的码表 以控制Response以什么码表向浏览器输出 默认IOS-8859-1 编码集
// 默认输出的编码集
// response.setHeader("Content-type", "text/html;charset=ISO-8859-1");
// 第一种方式 改变默认的响应头 把默认的编码集改成我们所需要的
// response.setHeader("Content-type", "text/html;charset = GB2312");
// 第二种方式设置CharacterEncoding编码集
//response.setCharacterEncoding("GB2312");
//第三种方式 设置contentType等价于 第一种方式和第二种方式的累加
response.setContentType("text/html;charset = GB2312");
PrintWriter out = response.getWriter();
out.write(data); //直接这样,乱码
}
首先在新建的Web工程的webRoot下新建download文件夹,把自己要下载的文件拷贝进去。
然后新建一个ServletDemo3,来完成从服务器下载文件
private void test1(HttpServletResponse response) {
String path=this.getServletContext().getRealPath("/download/4.jpg");//得到文件根路径
//System.out.println(path); //D:\Java\web_tomcat\apache-tomcat-7.0.62\webapps\JavaServlet\download\4.jpg
//得到文件的名字
String filename = path.substring(path.lastIndexOf("\\")+1); // "\"最后一次出现的位置
// System.out.println(filename); //4.jpg
//通过IO流往外写出数据
InputStream in = null;
OutputStream out =null;
//要想完成下载必须设置下载响应头信息
response.setHeader("content-disposition", "attzchment;filename=" + filename);
try {
in = new FileInputStream(path);
int hasRead=0;
byte [] buffer=new byte[1024];
out=response.getOutputStream();
while((hasRead = in.read(buffer))!= -1){
out.write(buffer,0,hasRead);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在网页上运行程序,自动跳出下载提示框:
(若文件名是中文时可能出现乱码,或者文件名不存在( . jpg)的情况)
String fname= URLEncoder.encode(filename,"UTF-8");
具体示例代码如下:
private void test2(HttpServletResponse response) throws IOException {
String path=this.getServletContext().getRealPath("/download/图片.jpg");
System.out.println(path);
String filename=path.substring(path.lastIndexOf("\\")+1);
//通过IO流往外写出数据
InputStream in =null;
OutputStream out =null;
//需要对下载的文件名进行编码
String fname= URLEncoder.encode(filename,"UTF-8");
//要想完成下载必须设置下载相应头信息
response.setHeader("content-disposition", "attachment;filename="+fname); //fname为编码之后的名字
try {
in=new FileInputStream(path);
int hasRead=0;
byte [] buffer=new byte[1024];
out=response.getOutputStream();
while((hasRead=in.read(buffer))!=-1){
out.write(buffer,0,hasRead);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(PS:有的浏览器的编码方式可能和其他浏览器的不同)
如火狐浏览器:
根据不同的浏览器进行编码,代码如下:
//根据不同的浏览器进行编码
private String encodDownFileName(String filename,String agent) throws IOException{ //agent代表使用的浏览器
if(agent.contains("Firefox")){
//火狐浏览器 需要单独编码
filename ="=?UTF-8?B?"+new BASE64Encoder().encode(filename.getBytes("UTF-8"))+"?=";
}else{
//IE或者其他浏览器
filename=URLEncoder.encode(filename,"UTF-8");
}
return filename; //返回编码好的名字
}
相应的调用程序,只需将获取的当前使用的浏览器作为参数传递给encodDownFileName();函数获得编码好的文件名即可
private void test3(HttpServletResponse response,HttpServletRequest request) throws IOException {
.......此处代码如上一个
//对下载的文件名进行编码
String fname=encodDownFileName(filename, request.getHeader("user-agent")); //通过request获取当前使用的浏览器
.........此处代码如上一个
}
编码后:
public class ResponseDemo4 extends HttpServlet {
// 1.定义一个随机字典
public static final char[] chars = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E','F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
//2 定义生成随机数
private static Random random = new Random();
//获取随机六位数
public static String getRandomString(){
//字符串缓冲 ,进行拼接
StringBuffer sb = new StringBuffer();
for(int i = 0;i <6;i++){
//每次获取一个随机字符串
sb.append(chars[random.nextInt(chars.length)]);
}
return sb.toString();
}
//获取一个颜色 分别用于前景色(文字的颜色)和背景色
public static Color getRandomColor(){
return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
//获取随机颜色的反色
public static Color getReverColor(Color c){
return new Color(255-c.getRed(), 255-c.getGreen(), 255-c.getBlue());
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置输出的类型
//随机字符串
String randomString = getRandomString();
//随机颜色 背景色
Color c =getRandomColor();
//反色 用于前景色
Color reverse =getReverColor(c);
//创建一个彩色的图片 根据BufferedImage(长度,宽度,生成的类型)
BufferedImage bi =new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);
//获取绘图对象,画笔
Graphics g = bi.getGraphics();
//设置字体
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,16));
//设置字体的颜色
g.setColor(c);
//绘制背景
g.fillRect(0, 0, 100, 30);
//设置前景色
g.setColor(reverse);
//绘制随机数字
g.drawString(randomString, 18, 20);
//加噪点
for(int i=0 ,n=random.nextInt(100);i100), random.nextInt(30), 1, 1);
}
//输出图片
ImageIO.write(bi,"jpg",response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
有两种情况:
(1)在本页面刷新;
(2)刷新跳转到其他页面。
public class ResponseDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
test2(response);
}
//(1)在本页面刷新
private void test1(HttpServletResponse response) throws IOException {
response.setHeader("refresh", "3"); //每隔3秒刷新一次
String data = new Random().nextInt(10000) + "";
response.getWriter().write(data);
}
//(2)刷新到其他的网页
private void test2(HttpServletResponse response) throws IOException{
response.setHeader("refresh","3;url=''/JavaServlet/Identity.html'"); //url:需要跳转的网页地址
//指定具体的编码集
response.setContentType("text/html;charset=GB2312");
response.getWriter().write("登陆成功,将在3秒之后跳转到首页 ,如果没有跳转,请点击首页");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}