Request和Response

第一章 Request原理和继承体系

1.1 Request的原理

  • ①服务器会根据请求url中的资源路径,创建对应的Servlet的对象。
  • ②服务器会创建request和response对象,request对象封装了请求消息数据,response对象封装了响应消息数据。
  • ③服务器将request和response对象传递给Servlet的service方法,并且调用service方法。
  • ④程序员可以来通过request对象来获取请求消息数据,可以通过response对象来设置响应消息数据。 
  • ⑤服务器在给浏览器做出响应之前,会从response对象中拿程序员设置的响应消息数据。

1.2 request的即成体系

 

 

第二章 Request获取请求数据

2.1 获取请求行数据

  • 格式:
# 请求方式  资源路径 http协议
GET /taobao/crm?username=zhangsan HTTP/1.1

 

  • 获取请求方式:
public String getMethod();

 

  • 获取虚拟目录:/taobao
public String getContextPath();

 

  • 获取Servlet路径:/crm
public String getServletPath();

 

  • 获取get方式请求参数:username=zhangsan
public String getQueryString();

 

  • 获取请求的URI:/taobao/crm
public String getRequestURI();

 

  • 获取请求的URL:http://localhost:8080/taobao/crm
public StringBuffer getRequestURL();

 

  • 获取协议及版本号:HTTP/1.1
public String getProtocol();

 

  • 获取客户端的IP地址:
public String getRemoteAddr();

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = {"/crm"})
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String method = req.getMethod();
        System.out.println("获取请求方式:" + method);

        String contextPath = req.getContextPath();
        System.out.println("获取虚拟目录:" + contextPath);

        String servletPath = req.getServletPath();
        System.out.println("获取Servlet的路径:" + servletPath);

        String queryString = req.getQueryString();
        System.out.println("获取get方式的参数格式:" + queryString);

        String requestURI = req.getRequestURI();
        System.out.println("获取请求的URI:" + requestURI);

        StringBuffer requestURL = req.getRequestURL();
        System.out.println("获取请求的URL:" + requestURL);

        String protocol = req.getProtocol();
        System.out.println("获取协议及版本号:" + protocol);

        String remoteAddr = req.getRemoteAddr();
        System.out.println("获取客户端的IP地址:" + remoteAddr);

    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

2.2 获取请求头数据

  • 根据请求名称获取请求头的值:
public String getHeader(String name);
public Enumeration<String> getHeaders(String name);

 

  • 获取所有的请求头:
public Enumeration<String> getHeaderNames();

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet(urlPatterns = {"/crm"})
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            Enumeration<String> headerValues = req.getHeaders(headerName);
            System.out.print("headerName:" + headerName + ",headerValues:");
            while (headerValues.hasMoreElements()) {
                System.out.print(headerValues.nextElement());
            }
            System.out.println();

        }
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

2.3 获取请求体数据

  • 请求体:只有post请求方式,才有请求体,在请求体中封装了post请求的请求参数。
  • 步骤:
  • ①获取流对象。
// 获取字符输入流,只能操作字符数据
public BufferedReader getReader() throws IOException;
// 获取字节输入流,可以操作所有类型数据
public ServletInputStream getInputStream() throws IOException;
  • ②从流中拿数据。

 

 

  • 示例:
  • register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册页面</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/register" method="post">
    用户名: <input type="text" name="username"/><br/>
    密码: <input type="password" name="password"/><br/>
    <input type="submit" value="登录">
</form>

</body>
</html>
  • RegisterServlet.java
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

@WebServlet(urlPatterns = {"/register"})
public class RegisterServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        BufferedReader reader = req.getReader();
        String str;
        while (null != (str = reader.readLine())) {
            System.out.println(str);
        }
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

2.4 其他功能

2.4.1 获取请求参数通用方式

  • 根据参数名获取参数值:
public String getParameter(String name);
public String[] getParameterValues(String name);

 

  • 获取所有的请求参数名称:
public Enumeration<String> getParameterNames();

 

  • 获取所有请求参数的Map集合:
public Map<String, String[]> getParameterMap();

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Enumeration;

@WebServlet(urlPatterns = {"/register"})
public class RegisterServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            String[] values = req.getParameterValues(parameterName);

            System.out.println("参数名:" + parameterName + ",参数值:" + Arrays.toString(values));
        }

    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

 

  • 中文乱码问题:在Tomcat8以后,GET方式没有乱码问题。
  • 对POST的乱码解决:
req.setCharacterEncoding("utf-8");

2.4.2 请求转发

  • 一种在服务器内部的资源跳转方式。

 

  • 步骤:
  • ①通过request对象获取请求转发器对象:
 public RequestDispatcher getRequestDispatcher(String path);
  • ②使用RequestDispatcher对象来进行转发:
public void forward(ServletRequest request, ServletResponse response){}

 

  • 特点:
  • ①浏览器的地址栏不会变化。
  • ②只能转发到当前服务器内部资源中。
  • ③转发是一次请求。

2.4.3 共享数据

  • 域对象:一个有作用范围的对象,可以在范围内共享数据。
  • request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据。

 

  • 在域中添加数据:
public void setAttribute(String name, Object o);

 

  • 在域中删除数据:
public void removeAttribute(String name);

 

  • 从域中获取数据:
public Object getAttribute(String name);

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo1", urlPatterns = "/servletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");

        request.setAttribute("msg", "你好,世界");

        request.getRequestDispatcher("/servletDemo2").forward(request, response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo2",urlPatterns = "/servletDemo2")
public class ServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");

        Object msg = request.getAttribute("msg");
        System.out.println(msg);


    }

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

2.4.4 获取ServletContext对象

  • 示例: 
package com.sunxiaping.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo1", urlPatterns = "/servletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        System.out.println("servletContext:" + servletContext);
    }

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

 

第三章 Response对象

3.1 概述

  • 代表响应信息。可以用来设置响应行、响应头、响应体。

 

  • 设置状态码:
public void setStatus(int sc);
public void setStatus(int sc, String sm);

 

  • 获取输出流:
public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;

 

  • 设置请求头:
public void setHeader(String name, String value);
public void setDateHeader(String name, long date);
public void addDateHeader(String name, long date);
public void addHeader(String name, String value);
public void setIntHeader(String name, int value);
public void addIntHeader(String name, int value);

3.2 重定向

  • 步骤:
  • ①告诉浏览器重定向的状态码是302.
  • ②告诉浏览器B资源的路径:通过响应头location。

 

  • 示例:
  • ServletDemo1.java
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo1", urlPatterns = "/servletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setStatus(302);
        response.setHeader("location", request.getContextPath()+"/servletDemo2");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • ServletDemo2.java
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo2",urlPatterns = "/servletDemo2")
public class ServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("这是ServletDemo2");

    }

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

 

  • 特点:
  • ①地址栏发生改变。
  • ②重定向可以访问其他站点(服务器)的资源。
  • ③重定向是两次请求。

3.3 response之输出数据

  • 示例:服务器输出字符数据到浏览器
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo1", urlPatterns = "/servletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置流的默认编码:iso-8859-1 为utf-8
        response.setCharacterEncoding("utf-8");

        //告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码
        response.setContentType("text/html;charset=utf-8");

        response.getWriter().println("你好啊,Servlet");
    }


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

 

  • 示例:服务器输出字节数据到浏览器
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletDemo1", urlPatterns = "/servletDemo1")
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");

        response.getOutputStream().write("你好啊".getBytes("utf-8"));
    }


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

 

第四章 ServletContext对象

4.1 概述

  • 代表整个web应用,可以和Servlet的容器(如Tomcat等)来通信。

4.2 功能

  • ①获取MIME类型。
  • ②域对象,共享数据。
  • ③获取文件的真实路径(服务器路径)。

4.3 获取ServletContext对象

  • 通过request对象获取ServletContext对象。
public ServletContext getServletContext();

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo", urlPatterns = "/servletContextDemo")
public class ServletContextDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = request.getServletContext();

        System.out.println("获取ServletContext对象:" + servletContext);
    }

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

4.4 获取MIME类型

  • MIME类型:在互联网通信过程中定义的一种文件数据类型。
  • 格式:大类型/小类型。

 

  • 根据文件名获取文件的MIME类型:
package com.sunxiaping.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo", urlPatterns = "/servletContextDemo")
public class ServletContextDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = request.getServletContext();

        String mimeType = servletContext.getMimeType("index.html");
        System.out.println("mimeType:" + mimeType);

    }

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

 

  • 实际中,会使用Apache的tika判断文件类型。
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>1.9</version>
</dependency>
  private static String getMimeType(File file) {
        if (file.isDirectory()) {
            return "the target is a directory";
        }

        AutoDetectParser parser = new AutoDetectParser();
        parser.setParsers(new HashMap<MediaType, Parser>());

        Metadata metadata = new Metadata();
        metadata.add(TikaMetadataKeys.RESOURCE_NAME_KEY, file.getName());

        InputStream stream;
        try {
            stream = new FileInputStream(file);
            parser.parse(stream, new DefaultHandler(), metadata, new ParseContext());
            stream.close();
        } catch (TikaException | SAXException | IOException e) {
            e.printStackTrace();
        }

        return metadata.get(HttpHeaders.CONTENT_TYPE);
    }

4.5 域对象(范围是整个web应用)

  • 设置属性:
public void setAttribute(String name, Object object);

 

  • 移除属性:
public void removeAttribute(String name);

 

  • 根据属性名获取属性值:
public Object getAttribute(String name);

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo", urlPatterns = "/servletContextDemo")
public class ServletContextDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = request.getServletContext();

        servletContext.setAttribute("username", "zhangsan");

        Object username = servletContext.getAttribute("username");
        System.out.println("username:" + username);
        

    }

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

4.6 获取文件在服务器中的路径

  • 获取文件的真实路径:
public String getRealPath(String path);

 

  • 示例:
package com.sunxiaping.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo", urlPatterns = "/servletContextDemo")
public class ServletContextDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = request.getServletContext();

        String realPath = servletContext.getRealPath("/index.jsp");

        System.out.println("realPath:" + realPath);
    }

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

 

第五章 文件下载

5.1 文件下载需求

  • ①页面显示超链接。
  • ②点击超链接后弹出下载提示框。
  • ③完成图片文件下载。

5.2 分析

  • ①超链接指向的资源如果能够被浏览器解析,则再浏览器中展示,如果不能被解析,则弹出下载提示框。
  • ②任何资源都必须弹出下载提示框。
  • ③使用响应头设置资源的打开方式:
content-disposition:attachment;filename=xxx

5.3 应用

  • 示例:
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<a href="${pageContext.request.contextPath}/download?filename=桌面背景.jpg">桌面背景.jpg</a>

</body>
</html>
  • DownloadServlet.java
package com.sunxiaping.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

@WebServlet(name = "DownloadServlet", urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        //获取文件名
        String filename = request.getParameter("filename");
        //设置响应头信息
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
        //找到文件服务器的路径
        String realPath = request.getServletContext().getRealPath("/image/" + filename);
        //创建InputStream对象
        InputStream inputStream = new FileInputStream(realPath);
        //获取OutputStream对象
        OutputStream outputStream = response.getOutputStream();

        byte[] bytes = new byte[1024];
        int len;
        while (-1 != (len = inputStream.read(bytes))) {
            outputStream.write(bytes, 0, len);
        }
    }

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

 

转载于:https://www.cnblogs.com/xuweiweiwoaini/p/11430638.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值