HttpServletResponse

Response:代表响应的对象.从服务器向浏览器输出内容。

Response的常用API

响应行:设置状态码。

  void setStatus(int sc)
          Sets the status code for this response.

响应头

* 针对一个key对应多个value的头信息

 void addDateHeader(String name, long date)
          Adds a response header with the given name and date-value.

 void addHeader(String name, String value)
          Adds a response header with the given name and value.

 void addIntHeader(String name, int value)
          Adds a response header with the given name and integer value.
          
 boolean containsHeader(String name)
          Returns a boolean indicating whether the named response header has already been set.

* 针对一个key对应一个value的头信息

 void setDateHeader(String name, long date)
          Sets a response header with the given name and date-value.

 void setHeader(String name, String value)
          Sets a response header with the given name and value.
          
 void setIntHeader(String name, int value)
          Sets a response header with the given name and integer value.

响应体

  ServletOutputStream getOutputStream()
          Returns a ServletOutputStream suitable for writing binary data in the response.
          
 PrintWriter getWriter()
          Returns a PrintWriter object that can send character text to the client.

登录页面跳转

public class UserRefreshServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            // 解决向页面输出中文的乱码问题!!!
            response.setContentType("text/html;charset=UTF-8");
            // 1.接收表单提交的参数.
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            // 2.封装到实体对象中.
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            
            // 3.调用业务层处理数据.
            UserService userService = new UserService();
        
            User existUser = userService.login(user);
            // 4.根据处理结果显示信息(页面跳转).
            if(existUser == null){
                // 登录失败
                response.getWriter().println("<h1>登录失败:用户名或密码错误!~</h1>");
            }else{
                // 登录成功
                // response.getWriter().println("Login Success...");
                response.getWriter().println("<h1>登录成功!您好:"+existUser.getNickname()+"</h1>");
                response.getWriter().println("<h3>页面将在5秒后跳转!</h3>");
                response.setHeader("Refresh", "5;url=/day09/demo5-refresh/index.html");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

}
登录页面跳转
更改上面的登录成功后的页面刷新为重定向:
    if(existUser == null){
        // 登录失败
        response.getWriter().println("<h1>登录失败:用户名或密码错误!~</h1>");
    }else{
        // 登录成功
        // response.getWriter().println("Login Success...");
        /*response.getWriter().println("<h1>登录成功!您好:"+existUser.getNickname()+"</h1>");
        response.getWriter().println("<h3>页面将在5秒后跳转!</h3>");
        response.setHeader("Refresh", "5;url=/day09/demo5-refresh/index.html");*/
        
        response.setStatus(302);
        // 重定向到success.html
        response.setHeader("Location", "/day09/demo5-refresh/success.html");
    }

success.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Refresh" content="5;url=/day09/demo5-refresh/index.html"/>
<!-- 上面meta标签的http-equiv属性和content属性的组合就相当于响应头和值 -->
<title>Insert title here</title>
<script type="text/javascript">
    var time = 5;
    window.onload = function(){
        setInterval('changeTime()',1000);
    }
    
    function changeTime(){
        time--;
        document.getElementById("s1").innerHTML = time;
    }
</script>
<!-- 数字的变化再用js来做修改 -->
</head>
<body>
<h1>登录成功!</h1>
<h3>页面将在<span id="s1">5</span>秒后跳转!</h3>
</body>
</html>
页面跳转的刷新改为重定向和读秒显示

文件的下载

一种:超链接下载.直接将文件的路径写到超链接的href中.---前提:文件类型,浏览器不支持.
二种:手动编写代码的方式完成文件的下载.
* 设置两个头和一个流:
* Content-Type:   文件的MIME的类型.
* Content-Disposition: 以下载的形式打开文件.
* InputStream:      文件的输入流.

下载的实现代码:

public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.接收参数
        String filename = new String(request.getParameter("filename").getBytes("ISO-8859-1"),"UTF-8");
        System.out.println(filename);
        // 2.完成文件下载:
        // 2.1设置Content-Type头
        String type = this.getServletContext().getMimeType(filename);
        response.setHeader("Content-Type", type);
        // 2.3设置文件的InputStream.
        String realPath = this.getServletContext().getRealPath("/download/"+filename);
        
        // 根据浏览器的类型处理中文文件的乱码问题:
        // IE浏览器下载中文文件的时候采用的URL的编码.
        // Firefox浏览器下载中文文件的时候采用的是Base64的编码.
        String agent = request.getHeader("User-Agent");
        System.out.println(agent);
        if(agent.contains("Firefox")){
            filename = base64EncodeFileName(filename);
        }else{
            filename = URLEncoder.encode(filename,"UTF-8");
        }
        
        // 2.2设置Content-Disposition头
        response.setHeader("Content-Disposition", "attachment;filename="+filename);
        
        InputStream is = new FileInputStream(realPath);
        // 获得response的输出流:
        OutputStream os = response.getOutputStream();
        int len = 0;
        byte[] b = new byte[1024];
        while((len = is.read(b))!= -1){
            os.write(b, 0, len);
        }
        is.close();
    }
    
    public static String base64EncodeFileName(String fileName) {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        try {
            return "=?UTF-8?B?"
                    + new String(base64Encoder.encode(fileName
                            .getBytes("UTF-8"))) + "?=";
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

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

}

response输出中文乱码的处理

* 字节流:
  * 设置浏览器默认打开的编码:
    * resposne.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
  * 设置中文字节取出的时候编码.
    * “中文”.getBytes(“UTF-8”);
* 字符流:
  * 设置浏览器打开的时候的编码
    * resposne.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
  * 设置response的缓冲区的编码,将字符以"UTF-8"编码输出到客户端浏览器
    * response.setCharacterEncoding(“UTF-8”);
  * 简化的写法:response.setContentType(“text/html;charset=UTF-8”);

request接收参数的中文乱码的处理

post请求

* 设置request的缓冲区的编码:
* request.setCharacterEncoding(“UTF-8”); --- 一定要在接收参数之前设置编码就OK.

get请求

* 1.修改 tomcat 的字符集编码(不推荐)。 confserver.xmlConnectorURIEncoding="utf-8"
* 2.使用URLEncoder和URLDecoder进行编码和解码的操作.
* 3.使用String的构造方法:
String name = request.getParameter("name");
name =new String(name.getBytes("ISO8859-1"), "UTF-8");

以post方式提交数据:
    浏览器将数据(假设为“中国”)发送给服务器的时候,将数据变成0101的二进制数据(假设为98 99)时必然要查码表,浏览器以哪个码表打开网页,浏览器就以哪个码表提交数据。数据到达服务器后,数据(98 99)要封装到request中,在servlet中调用Request的getParameter方法返回的是字符串(“中国”),方法内部拿到数字后要转成字符,一定要查码表,由于request的设计者是外国人,所以默认查的是他们常用的ISO8859-1,这就是请求数据产生乱码的根源。

以get方式提交数据:
   get方式提交的数据依然是浏览器用什么码表打开就用什么码表发送。不同的是,以get方式提交数据时,request设置编码无效。即使设置了UTF-8还是会去查ISO8859-1。得到(? ?),要解决这个问题,需要拿着(??)反向查ISO8859-1,拿到(98 99)后,再去查正确码表。
接收请求乱码的原因

重定向和转发区别

重定向: response.sendRedirect(request.getContextPath()+"/ListServlet?method=findAll"); //全路径
转发: request.getRequestDispatcher("/jsp/XXX.jsp").forward(request, response); //不含工程名的相对路径
1.重定向的地址栏会发生变化,转发的地址栏不变.
2.重定向两次请求两次响应,转发一次请求一次响应.
3.重定向路径需要加工程名,转发的路径不需要加工程名.
4.重定向可以跳转到任意网站,转发只能在服务器内部进行转发.
5.重定向的过程中,传输的信息会被丢失。转发不会。

转发过程:客户浏览器发送http请求——> web服务器接受此请求 ——>调用内部的一个方法在容器内部完成请求处理和转发动作 ——> 将目标资源发送给客户。在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。

重定向过程:客户浏览器发送http请求——> web服务器接受后发送302状态码响应及对应新的location给客户浏览器 ——> 客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址 ——> 服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。

addHeader与setHeader区别

1、同名Header可以有多个 ,Header[] getHeaders(String name)。
2、运行时使用的是第一个, Header getFirstHeader(String name)。
3、addHeader,如果同名header已存在,则追加至原同名header后面。
4、setHeader,如果同名header已存在,则覆盖一个同名header。

Request作为域对象存取数据

使用request对象存取数据:
* setAttribute(String name,String value);
* Object getAttribute(String name);

request的作用范围:
* 作用范围就是一次请求的范围
* 创建和销毁:
    * 创建:客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象。
    * 销毁:当服务器对这次请求作出了响应之后。

原文地址:https://www.cnblogs.com/boomoom/p/10134894.html