Response

1.HttpServletResponse概述

我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。

service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大

response的运行过程

1.通过response设置响应行

设置响应行的状态码

setStatus(int sc)

2.通过response设置响应头

addHeader(String name, String value)

addIntHeader(String name, int value)

addDateHeader(String name, long date)

setHeader(String name, String value)

setDateHeader(String name, long date)

setIntHeader(String name, int value)

其中,add表示添加,而set表示设置(不同之处)

重定向:状态码302 响应头location 代表重定向的地址

//        response.getWriter().write("doGet runing...");
//        response.setStatus(302);
//        response.setHeader("location", "/web14/redirect2");
        //封装成一个重定向的方法
        response.sendRedirect("/web/redirect2");
重定向

定时刷新:response.setHeader("refresh", "5;url=https://www.baidu.com");

js完成页面成功跳转

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    window.onload = function(){
        var time = 5;
        var secondEle = document.getElementById("second");
        var timer = setInterval(function(){
            secondEle.innerHTML = time;
            time--;
            if(time==0){
                clearInterval(timer);
                location.href="http://www.baidu.com";
            }
                
        },1000);
    }
</script>
</head>
<body>
    恭喜你,注册成功,<span style="color:red" id="second">5</span>秒钟后跳转,如不跳转点击<a href="http://www.baidu.com">这里</a>!
</body>
</html>
View Code

 

设置响应体

(1)响应体设置文本

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的outputstream输出图片,完成outstream

ServletOutputStream  getOutputStream()

获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。

package com.heima.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;


import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



public class ByteServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        //使用response获得字节输出流
        ServletOutputStream out = response.getOutputStream();
        //获得服务器上的图片
        String realPath = this.getServletContext().getRealPath("a.jpg");//图片在WebContent下
        System.out.println(realPath);
        InputStream in =new FileInputStream(realPath);
        int len=0;
        byte[] buffer=new byte[1024];
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
response图片

文件下载

1什么情况下回文件下载?浏览器不能解析的文件

2什么情况下需要在服务器端编写文件下载的代码?  浏览器可以解析的代码需要编写文件下载代码。实际上,只要是下载的文件都编写下载代码

package com.heima.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DownloadServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        String filename=request.getParameter("filename");
        //在响应头中设置要的这个文件的类型,客户端通过文件的mime类型去区分类型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //告诉客户端该文件不是直接解析 而是以附件形式打开下载
        response.setHeader("Content-Disposition","attachment;filename="+filename);
        
        String path=this.getServletContext().getRealPath("download/"+filename);
        //获得文件的输入流
        InputStream in = new FileInputStream(path);
        //获得输出流--通过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();
        
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
/web14/src/com/heima/content/DownloadServlet.java

文件下载代码解析过程问题:

1。url传递参数filename,reques方法获得,结合filename获得文件绝对路径path,根据文件路径获得输入流FileInputStream

2.response对象方法 获得输出流,response响应体,  从输入流到输出流文件拷贝。

3.response传递文件初步完成,存在问题:客户端会对图片自动解析,对其他类型会下载。(需求:所有类型文件下载)

4.告诉客户端文件非解析,是一附件形式下载----》客户端文件下载需要告知文件类型---->客户端通过MIME类型(例子Content-type: text/html)区分

//在响应头中设置要的这个文件的类型,客户端通过文件的mime类型去区分类型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //告诉客户端该文件不是直接解析 而是以附件形式打开下载
        response.setHeader("Content-Disposition","attachment;filename="+filename);
1.告诉浏览器设置下载而不是解析打开2.告诉客户端文件类型MIME

 

中文文件下载过程分析:

1.其他过程与上面文件下载相同   本地eclipse中文文件参数filename不能解析出来,显示乱码,通过string转码解决

2.浏览器收到respose中的中文文件名进行解码,各个浏览器解码不同,解码乱码.  表现为,下载文件没有文件名,下载后没有文件名(文件内容)

3.解决办法,根据reques中的参数agent进行区分客户端浏览器, 对文件编码采取和浏览器相同的编码方式,再次编码.  response

//获得要下载的文件的名称
        String filename = request.getParameter("filename");//????.jpg
        //解决获得中文参数的乱码----下节课讲
        filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg

        
        //获得请求头中的User-Agent
        String agent = request.getHeader("User-Agent");
        //根据不同浏览器进行不同的编码
        String filenameEncoder = "";
        if (agent.contains("MSIE")) {
            // IE浏览器
            filenameEncoder = URLEncoder.encode(filename, "utf-8");
            filenameEncoder = filenameEncoder.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filenameEncoder = "=?utf-8?B?"
                    + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filenameEncoder = URLEncoder.encode(filename, "utf-8");                
        }
中文乱码问题
package com.heima.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

public class DownloadServlet2 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String filename=request.getParameter("filename");//美女.jpg乱码
        filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//转码
        System.out.println(filename);
        
        //获得请求头中的User-Agent
                String agent = request.getHeader("User-Agent");
                System.out.println(agent);
                //根据不同浏览器进行不同的编码
                String filenameEncoder = "";
                if (agent.contains("MSIE")) {
                    // IE浏览器
                    filenameEncoder = URLEncoder.encode(filename, "utf-8");
                    filenameEncoder = filenameEncoder.replace("+", " ");
                } else if (agent.contains("Firefox")) {
                    // 火狐浏览器
                    BASE64Encoder base64Encoder = new BASE64Encoder();
                    filenameEncoder = "=?utf-8?B?"
                            + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
                } else {
                    // 其它浏览器
                    filenameEncoder = URLEncoder.encode(filename, "utf-8");                
                }
        
        
        //在响应头中设置要的这个文件的类型,客户端通过文件的mime类型去区分类型
        response.setContentType(this.getServletContext().getMimeType(filename));
        //告诉客户端该文件不是直接解析 而是以附件形式打开下载
        response.setHeader("Content-Disposition","attachment;filename="+filenameEncoder);
        
        String path=this.getServletContext().getRealPath("download/"+filename);
        //获得文件的输入流
        InputStream in = new FileInputStream(path);
        //获得输出流--通过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();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
View Code

response细节:

1.response获得的流不需要手动关闭,tomcat容器会帮我们关闭

2.getWrite 和 getOutputStream不能同时调用

 

实现验证码功能

package com.itheima.checkimg;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 验证码生成程序
 * 
 * 
 * 
 */
public class CheckImgServlet extends HttpServlet {

    // 集合中保存所有成语
    private List<String> words = new ArrayList<String>();

    @Override
    public void init() throws ServletException {
        // 初始化阶段,读取new_words.txt
        // web工程中读取 文件,必须使用绝对磁盘路径
        String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String line;
            while ((line = reader.readLine()) != null) {
                words.add(line);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 禁止缓存
        // response.setHeader("Cache-Control", "no-cache");
        // response.setHeader("Pragma", "no-cache");
        // response.setDateHeader("Expires", -1);

        int width = 120;
        int height = 30;

        // 步骤一 绘制一张内存中图片
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        // 步骤二 图片绘制背景颜色 ---通过绘图对象
        Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
        // 绘制任何图形之前 都必须指定一个颜色
        graphics.setColor(getRandColor(200, 250));
        graphics.fillRect(0, 0, width, height);

        // 步骤三 绘制边框
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, 0, width - 1, height - 1);

        // 步骤四 四个随机数字
        Graphics2D graphics2d = (Graphics2D) graphics;
        // 设置输出字体
        graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

        Random random = new Random();// 生成随机数
        int index = random.nextInt(words.size());
        String word = words.get(index);// 获得成语

        // 定义x坐标
        int x = 10;
        for (int i = 0; i < word.length(); i++) {
            // 随机颜色
            graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 旋转 -30 --- 30度
            int jiaodu = random.nextInt(60) - 30;
            // 换算弧度
            double theta = jiaodu * Math.PI / 180;

            // 获得字母数字
            char c = word.charAt(i);

            // 将c 输出到图片
            graphics2d.rotate(theta, x, 20);
            graphics2d.drawString(String.valueOf(c), x, 20);
            graphics2d.rotate(-theta, x, 20);
            x += 30;
        }

        // 将验证码内容保存session
        request.getSession().setAttribute("checkcode_session", word);

        // 步骤五 绘制干扰线
        graphics.setColor(getRandColor(160, 200));
        int x1;
        int x2;
        int y1;
        int y2;
        for (int i = 0; i < 30; i++) {
            x1 = random.nextInt(width);
            x2 = random.nextInt(12);
            y1 = random.nextInt(height);
            y2 = random.nextInt(12);
            graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
        }

        // 将上面图片输出到浏览器 ImageIO
        graphics.dispose();// 释放资源
        
        //将图片写到response.getOutputStream()中
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * 取其某一范围的color
     * 
     * @param fc
     *            int 范围参数1
     * @param bc
     *            int 范围参数2
     * @return Color
     */
    private Color getRandColor(int fc, int bc) {
        // 取其随机颜色
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

}
servlet
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    window.onload = function(){
        
    }
    
    function changeImg(obj){
        obj.src="/WEB14/checkImg?time="+new Date().getTime();
    }

    
</script>

</head>
<body>    
    <form action="/WEB13/login" method="post">
        用户名:<input type="text" name="username"><br/>
        密码:<input type="password" name="password"><br/>
        验证码:<input type="text" name="username"><img onclick="changeImg(this)" src="/WEB14/checkImg"><br/>
        <input type="submit" value="登录"><br/>
    </form>
</body>
</html>
html

 

posted on 2018-08-01 17:32  打酱油的地方  阅读(279)  评论(0编辑  收藏  举报

导航