Response

Response
 
一、Response的运行过程
 
客户端发送请求(http请求)---->Tomcat引擎(解析,内部封装request信息以及response空对象)------>对应的Web程序的Servlet-------->然后将Response响应放到response缓冲区(类似)------->Tomcat引擎取出Response缓冲区内容------>Tomcat引擎将Response缓冲区内容与引擎自己添加的信息组装成一个http响应发送给客户端
 
http响应(三部分):
http响应行
http响应头
http响应体
 
1、通过Response设置响应行
 设置响应行的状态码
    setStatus( int sc )
//手动设置http响应行中的状态码
             response.setStatus(302);
 
2、通过Response设置响应头
addHeader(String name, String value)
addIntHeader(String name, int value)
addDateHeader(String name, long date)
Date date = new Date();
             //设置响应头
             response.addHeader("name", "zhangsan");
             response.addIntHeader("age", 28);
             response.addDateHeader("birthday", date.getTime());
 
setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)
 
其中,add表示添加(同名,会添加多个),而set表示设置(同名的,后面的会覆盖前面的)。
 
注:自己通过抓包查看响应信息。
 
3、重定向
什么是重定向?
客户端找servlet1要资源,servlet1没有资源,但知道servlet2有资源,然后告诉客户端,客户端去找servlet2要资源的过程就叫重定向。
俗话理解:你找张三借钱,张三没钱,但知道李四有钱,然后告诉你李四有钱,让你去找李四借钱。
特定:a、访问服务器两次或多次。b、地址栏的地址发生变化(自动变化)
 
怎样设定重定向?
状态码:302        响应头:location  (代表重定向的地址)
             //没有响应,告知客户端去重定向到Servlet2
             //1.设置状态码302
             response.setStatus(302);
             //2.设置响应头location
             response.setHeader("Location", "/WEB14_Response/servlet2");
//JavaEE已经封装了一个重定向的方法sendRedirect(url)
             response.sendRedirect("/WEB14_Response/servlet2");
替代上面代码。
 
设置定时刷新,也能够达到重定向的功能!
//设置定时刷新的头,5秒回刷新到百度
             response.setHeader("refresh", "5;url=http://www.baidu.com";);
 
4、通过Response设置响应体
a、响应体设置文本
PrintWriter  writer = response.getWriter();
writer.write("hello China");
writer.write("中国!!!");
中文乱码问题?
通知Response查询UTF-8的码表,需要在输出流之前设置。
            //设置Response查询的码表
             //response.setCharacterEncoding("UTF-8");
             
             //通过一个头Content-Type,告知客户端使用的编码表
             //response.setHeader("Content-Type", "text/html;charset=UTF-8");
             
             //封装的方法
             response.setContentType("text/html;charset=UTF-8");
             
             PrintWriter  writer = response.getWriter();
             writer.write("hello China");
             writer.write("中国!!!");
 
PrintWriter getWriter()
获得字符流,通过字符流的write(String s)方法可以将字符串设置到response    缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
 
关于设置中文的乱码问题
原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过response的setCharacterEncoding(String charset) 设置response的编码。
 
但我们发现客户端还是不能正常显示文字
原因:我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系统的编码,因为我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以手动修改浏览器的编码是UTF-8。我们还可以在代码中指定浏览器解析页面的编码方式,通过response的setContentType(String type)方法指定页面解析时的编码是UTF-
8。response.setContentType("text/html;charset=UTF-8");
上面的代码不仅可以指定浏览器解析页面时的编码,同时也内含setCharacterEncoding的功能,所以在实际开发中只要编写   
response.setContentType("text/html;charset=UTF-8");
就可以解决页面输出中文乱码问题。
注意:上述红色代码只能在response页面输出前生效,如果页面先有输出(非中文等),再写上述代码,再输出中文,还是不能解决中文乱码问题。
 
b、响应头设置字节
//使用response获得字节输出流
ServletOutputStream outputStream = response.getOutputStream();
 
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。
             //使用response获得字节输出流
             ServletOutputStream outputStream = response.getOutputStream();
             
             //获得服务器上的图片
             String realPath = this.getServletContext().getRealPath("/WEB-INF/a.jpg");
             InputStream in = new FileInputStream(realPath);
             
             int  len = 0;
             byte[] buffer = new byte[1024];
             while ((len = in.read(buffer))>0) {
                    outputStream.write(buffer, 0, len);                  
             }
             in.close();
             outputStream.close();
 
二、文件下载的基本代码
问题:
        a、什么情况下会文件下载?
        浏览器不能解析的文件就下载。
        b、什么情况下需要在服务器端编写文件下载的代码?
        理论上,浏览器可以解析的代码需要编写文件下载代码。
        实际开发中,只要是下载的文件都编写文件代码下载。       
 
1、文件下载的本质
        文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需要IO技术将服务器端的文件使用InputStream读取到,再使用ServletOutputStream写到response缓冲区中。
//使用response获得字节输出流
             ServletOutputStream outputStream = response.getOutputStream();
             //获得服务器上的图片
             String realPath = this.getServletContext().getRealPath("/WEB-INF/a.jpg");
             InputStream in = new FileInputStream(realPath);
             int  len = 0;
             byte[] buffer = new byte[1024];
             while ((len = in.read(buffer))>0) {
                    outputStream.write(buffer, 0, len);                  
             }
             in.close();
             outputStream.close();
 
上述代码可以将图片从服务器端产生到浏览器,但浏览器直接解析图片显示在页面上,而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方式。
a、告知浏览器文件的类型:
response.setContentType(文件的MIME类型)
response.setContentType(this.getServletContext().getMimeType(filename));
b、告知浏览器文件的打开方式是下载:
response.setHeader("Content-Disposition","attachment;filename=文件名称");
//告诉客户端该文件不是直接解析,而是以附件形式打开(下载)
             response.setHeader("Content-Disposition", "attachment;filename="+filename);
             //获得要下载文件的名称
             String filename = request.getParameter("filename");         
             
             //要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
             //MIME:字符串
              response.setContentType(this.getServletContext().getMimeType(filename));
             
             //告诉客户端该文件不是直接解析,而是以附件形式打开(下载)
             response.setHeader("Content-Disposition", "attachment;filename="+filename);
                           
             //获得文件的绝对路径
             String realPath = this.getServletContext().getRealPath("download/" + filename);
             //获得该文件的输入流
             InputStream  in = new FileInputStream(realPath);
             //获得输出流--通过response获得的输出流,用于向客户端写内容
             ServletOutputStream out = response.getOutputStream();
             //文件拷贝的模板代码
             int len = 0;
             byte[] buffer = new byte[1024];
             while ((len = in.read(buffer)) >0) {
                    out.write(buffer, 0, len);
             }
             in.close();
             out.close();        
 
解决乱码的问题:
解决乱码方法如下(不要记忆--了解):
if (agent.contains("MSIE")) {
        // IE浏览器
        filename = URLEncoder.encode(filename, "utf-8");
        filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
        // 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
        filename = "=?utf-8?B?"
                + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
        // 其它浏览器
        filename = URLEncoder.encode(filename, "utf-8");                
}
 
download.html
<body>
       <h1>使用服务器编码实现文件下载</h1>
       <a href="/WEB14_Response/downloadServlet?filename=a.flv">a.flv</a><br>
       <a href="/WEB14_Response/downloadServlet?filename=a.jpg">a.jgp</a><br>
       <a href="/WEB14_Response/downloadServlet?filename=a.mp3">a.mp3</a><br>
       <a href="/WEB14_Response/downloadServlet?filename=a.mp4">a.mp4</a><br>
       <a href="/WEB14_Response/downloadServlet?filename=a.txt">a.txt</a><br>
       <a href="/WEB14_Response/downloadServlet?filename=a.zip">a.zip</a><br>
       <a href="/WEB14_Response/downloadEncode?filename=美女.jpg">美女.jpg</a><br>
</body>
 
downloadEncodeServlet.java
//获得要下载文件的名称
             String filename = request.getParameter("filename");  //美女.jpg
             System.out.println(filename);
             //解决获得中文参数的乱码
             //filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");
             
             //获得请求头中的User-Agent
             String agent = request.getHeader("User-Agent");
             String filenameEncode = "";
             //根据不同得了浏览器进行不同的编码
             if (agent.contains("MSIE")) {
                    // IE浏览器
                    filenameEncode = URLEncoder.encode(filename, "utf-8");
                    filenameEncode = filenameEncode.replace("+", " ");
             } else if (agent.contains("Firefox")) {
                    // 火狐浏览器
                    BASE64Encoder base64Encoder = new BASE64Encoder();
                    filenameEncode = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
             } else {
                    // 其它浏览器
                    filenameEncode = URLEncoder.encode(filename, "utf-8");
             }
 
             //要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
             //MIME:字符串
              response.setContentType(this.getServletContext().getMimeType(filename));
             
             //告诉客户端该文件不是直接解析,而是以附件形式打开(下载)
             response.setHeader("Content-Disposition", "attachment;filename="+filenameEncode);
             
                           
             //获得文件的绝对路径
             String realPath = this.getServletContext().getRealPath("download/" + filename);
             //System.out.println("realPath:"+realPath);
             //获得该文件的输入流
             InputStream  in = new FileInputStream(realPath);
             //获得输出流--通过response获得的输出流,用于向客户端写内容
             ServletOutputStream out = response.getOutputStream();
             //文件拷贝的模板代码
             int len = 0;
             byte[] buffer = new byte[1024];
             while ((len = in.read(buffer)) >0) {
                    out.write(buffer, 0, len);
             }
             in.close();
             out.close(); 
 
 
其中agent就是请求头User-Agent的值。
 
response细节点:
a、response 获得的流不需要手动关闭,Tomcat容器会帮助我们关闭
b、getWriter 和 getOutputStream不能同时调用
 

java下载文件的中文名 为什么要用 new String(fileName.getBytes("gb2312"),"iso8859-1");原因是什么?

 
三、实现验证码功能
 
通过java代码或者其他生产验证码的过程,不需要很了解。但是生产的验证码图片,需要掌握怎样使用!!!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/scalpel-ct/p/7502988.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值