第10章WEB10-request&response篇

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第10章WEB10-request&response篇相关的知识,希望对你有一定的参考价值。

今日任务
? WEB工程下的文件的读取
? 登录系统后完成文件下载
? 商城系统注册功能.
教学导航
教学目标
掌握response设置响应头
掌握response重定向和转发的区别
掌握request接收请求参数
掌握request域的作用范围
教学方法
案例驱动法
1.1 上次课内容回顾:
HTTP :

  • Http请求部分:
    • 请求行:请求方式 请求路径 协议版本.
      • 请求方式:
        • 请求有很多.常用的是GET和POST.
        • 区别:get有大小限制,post没有大小限制,get参数会显示到地址栏,post不会显示到地址栏,放入请求体中.
    • 请求头:键值对.
      • Referer:网页来源.
      • User-Agent:浏览器信息.
      • If-Modified-Since:
    • 请求体
      • POST提交参数.
  • Http响应部分:
    • 响应行:协议版本 状态码 状态码描述
      • 200,302,304,404,500
    • 响应头:键值对.
      • Location:重定向.
      • Refresh:定时跳转
      • Content-Disposition:文件下载
      • Last-Modified
    • 响应体
      • 显示到页面的内容.
        Servlet :
  • Servlet的概述:SUN公司提供动态网页开发规范,就是一个小的java程序运行在服务器端的.
  • Servlet的入门:
  • Servlet的生命周期:
    • 第一次访问该Servlet的时候,服务器创建一个Servlet的实例,init方法就会执行.任何一次从客户端发送的请求服务器都会创建一个新的线程执行service方法,在service方法内部根据请求方式调用不用的doXXX的方法.当项目从服务器中移除,或者关闭服务器的时候,就会销毁Servlet,destroy方法就会执行.
  • Servlet的相关配置:
    • 启动时加载:
    • url-pattern:
      • 完全路径匹配
      • 目录匹配
      • 扩展名匹配
  • Servlet的继承关系:
    • Servlet

      GenericServlet

      HttpServlet

  • ServletConfig对象:用来获得Servlet的配置信息.
  • ServletContext对象:

    • 1.获得全局初始化参数
    • 2.获得文件的MIME的类型
    • 3.作为域对象存取数据.
    • 4.读取web项目中的文件.
      1.2 案例一:读取WEB工程下的文件.1.2.1 需求:
      现在有一个配置文件在web工程的src下,项目要发布到tomcat中,需要编写一段程序读取文件.
      1.2.2 分析:1.2.2.1 技术分析:
      【演示传统方式读取WEB工程文件】
      /**

      • 传统方式读取文件:
        • 使用的是相对路径,相对的JVM的路径.
        • 但是现在是一个web项目,相对于JVM的路径的.现在JVM已经交给tomcat管理.
      • @throws FileNotFoundException
      • @throws IOException
        */
        private void test1() throws FileNotFoundException, IOException {
        InputStream is = new FileInputStream("src/db.properties");
        Properties properties = new Properties();
        properties.load(is);

        String driverClass = properties.getProperty("driverClass");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        
        System.out.println(driverClass);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);

        }
        【使用ServletContext对象读取WEB项目下的文件】
        技术分享图片

  • InputStream getResourceAsStream(String path); --- 根据提供路径读取文件返回一个文件的输入流.
    技术分享图片
  • String getRealPath(String path); --- 返回一个路径的磁盘绝对路径.
    1.2.3 代码实现:1.2.3.1 使用getResourceAsStream读取

/**

  • 使用ServletContext中的getResourceAsStream读取.
  • @throws FileNotFoundException
  • @throws IOException
    */
    private void test2() throws FileNotFoundException, IOException {
    // 获得ServletContext:
    ServletContext context = this.getServletContext();
    InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
    Properties properties = new Properties();
    properties.load(is);
    String driverClass = properties.getProperty("driverClass");
    String url = properties.getProperty("url");
    String username = properties.getProperty("username");
    String password = properties.getProperty("password");
    System.out.println(driverClass);
    System.out.println(url);
    System.out.println(username);
    System.out.println(password);
    }
    
    1.2.3.2 使用getRealPath读取文件:
/**
 * 使用ServletContext中的getRealPath读取.
 * @throws FileNotFoundException
 * @throws IOException
 */
private void test3() throws FileNotFoundException, IOException {
// 获得ServletContext:
ServletContext context = this.getServletContext();
String realPath = context.getRealPath("/WEB-INF/classes/db.properties");
// 获得该文件的磁盘绝对路径.
System.out.println(realPath);
InputStream is = new FileInputStream(realPath);
Properties properties = new Properties();
properties.load(is);
String driverClass = properties.getProperty("driverClass");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driverClass);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}

1.2.4 总结:1.2.4.1 ServletContext的功能:
【功能一:读取全局初始化参数】
技术分享图片

配置全局初始化参数:
  <context-param>
          <param-name>username</param-name>
          <param-value>root</param-value>
  </context-param>
    <context-param>
          <param-name>password</param-name>
          <param-value>123</param-value>
  </context-param>

代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = this.getServletContext().getInitParameter("username");
String password = this.getServletContext().getInitParameter("password");
System.out.println(username+"    "+password);
Enumeration<String> e = this.getServletContext().getInitParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
String value = this.getServletContext().getInitParameter(name);
System.out.println(name+"    "+value);
}
}

【功能二:获得文件的MIME的类型】
技术分享图片

  • 获得文件的MIME的类型.
    代码实现:
       /**
         * 获得文件的MIME的类型
         */
        private void test2() {
                String type = this.getServletContext().getMimeType("1.html");
                System.out.println(type);
        }

    【功能三:作为域对象存取数据】
    范围:整个web项目.而且全局的对象.
    创建:服务器启动的时候,服务器为每个web项目创建一个单独的ServletContext对象.
    销毁:服务器关闭的时候销毁ServletContext.
    【功能四:读取web项目下的文件】
    1.2.4.2 类加载器读取文件:(扩展)

public static void readFile() throws IOException{
// 使用类的加载器来读取文件.
// 类的加载器用来加载class文件,将class文件加载到内存.
InputStream is = ReadFileUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(is);
String driverClass = properties.getProperty("driverClass");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driverClass);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}

1.3 案例二:登录成功后,完成文件的下载.1.3.1 需求:
在登录成功后,页面跳转到文件下载的列表的页面,点击列表中的某些链接,下载文件.
1.3.2 分析:1.3.2.1 技术分析:
【Response的概述】
? Response:代表响应的对象.从服务器向浏览器输出内容.
【Response的常用的API】
? 响应行:
技术分享图片

  • 设置状态码.
    ? 响应头:
    技术分享图片
  • 针对一个key对应多个value的头信息.
    技术分享图片
  • 针对一个key对应一个value的头信息.
    ? 响应体
    技术分享图片
    【文件下载的方式】
    ? 一种:超链接下载.直接将文件的路径写到超链接的href中.---前提:文件类型,浏览器不支持.
    ? 二种:手动编写代码的方式完成文件的下载.
  • 设置两个头和一个流:
    • Content-Type :文件的MIME的类型.
    • Content-Disposition :以下载的形式打开文件.
    • InputStream :文件的输入流.
      1.3.3 代码实现1.3.3.1 步骤一:将之前的登录功能准备好:
      1.3.3.2 步骤二:在文件下载列表页面上添加文件下载的链接:
      1.3.3.3 步骤三:完成文件下载的代码的实现:
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.接收参数
String filename = request.getParameter("filename");
// 2.完成文件下载:
// 2.1设置Content-Type头
String type = this.getServletContext().getMimeType(filename);
response.setHeader("Content-Type", type);
// 2.2设置Content-Disposition头
response.setHeader("Content-Disposition", "attachment;filename="+filename);
// 2.3设置文件的InputStream.
String realPath = this.getServletContext().getRealPath("/download/"+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();
}

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

}

1.3.4 总结:1.3.4.1 中文文件的下载:

? IE浏览器下载中文文件的时候采用的URL的编码.
? Firefox浏览器下载中文文件的时候采用的是Base64的编码.
/**
 * 文件下载的Servlet
 */
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);
// 根据浏览器的类型处理中文文件的乱码问题:
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);
}

}

1.3.4.2 response输出响应内容的方法:
向页面响应的方法:

  • getOutputStream();
  • getWriter();
  • 这两个方法是互斥的.
    • 做出响应的时候只能使用其中的一种流响应.
  • 输出中文乱码的处理:
    • 字节流:
      • 设置浏览器默认打开的编码:
        • resposne.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
      • 设置中文字节取出的时候编码.
        • “中文”.getBytes(“UTF-8”);
    • 字符流:
      • 设置浏览器打开的时候的编码
        • resposne.setHeader(“Content-Type”,”text/html;charset=UTF-8”);
      • 设置response的缓冲区的编码
        • response.setCharacterEncoding(“UTF-8”);
          ***** 简化的写法:response.setContentType(“text/html;charset=UTF-8”);
          1.4 案例三:完成用户注册的功能:1.4.1 需求:
          网站首页上点击注册的链接,跳转到注册页面,在注册页面中输入信息.完成注册:(将数据保存到数据库中).
          技术分享图片
          1.4.2 分析:1.4.2.1 技术分析:
          【Request的概述】
          ? Request代表用户的请求.
          【Request的API】
          功能一:获得客户机相关的信息
          ? 获得请求方式:
          技术分享图片
          ? 获得请求的路径:
          技术分享图片
          ? 获得客户机相关的信息:
          技术分享图片
          ? 获得工程名:
          技术分享图片
          功能二:获得从页面中提交的参数:
          技术分享图片
          功能三:作为域对象存取数据:
          技术分享图片
          技术分享图片
          【演示request获得客户机的信息】
public class RequestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获得请求方式:
String method = request.getMethod();
System.out.println("请求方式:"+method);
// 获得客户机的IP地址:
String ip = request.getRemoteAddr();
System.out.println("IP地址:"+ip);
// 获得用户的请求的路径:
String url = request.getRequestURL().toString();
String uri = request.getRequestURI();
System.out.println("获得请求的URL:"+url);
System.out.println("获得请求的URI:"+uri);
// 获得发布的工程名:
String contextPath = request.getContextPath();
System.out.println("工程名:"+contextPath);
}

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

}

1.4.3 代码实现:1.4.3.1 步骤一:创建数据库和表:

create database day10;
use day10;
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(20),
email varchar(20),
name varchar(20),
sex varchar(10),
telephone varchar(20)
);

1.4.3.2 步骤二:创建包和类:
1.4.3.3 步骤三:引入注册页面:
1.4.3.4 步骤四:注册代码的实现:
1.4.4 总结:1.4.4.1 处理request接收参数的中文乱码的问题:
现在无论是GET还是POST提交中文的时候,都会出现乱码的问题.
解决:
? POST的解决方案:

  • POST的参数在请求体中,直接到达后台的Servlet.数据封装到Servlet中的request中.request也有一个缓冲区.request的缓冲区也是ISO-8859-1编码.
  • 设置request的缓冲区的编码:
    • request.setCharacterEncoding(“UTF-8”); --- 一定要在接收参数之前设置编码就OK.
      ? GET的解决方案:
  • 1.修改tomcat的字符集的编码.(不推荐)
  • 2.使用URLEncoder和URLDecoder进行编码和解码的操作.
  • 3.使用String的构造方法:
    技术分享图片
    1.4.4.2 Request作为域对象存取数据:
    使用request对象存取数据:
  • setAttribute(String name,String value);
  • Object getAttribute(String name);
    request的作用范围:
  • 作用范围就是一次请求的范围.
  • 创建和销毁:
    • 创建:客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象.
    • 销毁:当服务器对这次请求作出了响应之后.
      1.4.4.3 重定向和转发的区别:(redirect和forward的区别)
  • 1.重定向的地址栏会发生变化,转发的地址栏不变.
  • 2.重定向两次请求两次响应,转发一次请求一次响应.
  • 3.重定向路径需要加工程名,转发的路径不需要加工程名.
  • 4.重定向可以跳转到任意网站,转发只能在服务器内部进行转发.

以上是关于第10章WEB10-request&response篇的主要内容,如果未能解决你的问题,请参考以下文章

第12章WEB12-JSP&EL&JSTL篇

第11章WEB11-Cookie&Session篇

第2章WEB02-CSS&JS篇

第13章WEB13-JSP模式&JDBC高级篇

微信开发第6章 通过accesstoken获取用户粉丝列表

微信开发第2章 通过appid appsecret获取accesstoken