A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

day15-request和response读取WEB工程下的文件使用ServletContext对象读取WEB项目下的文件
  • InputStream getResourceAsStream(String path); --- 根据提供路径读取文件返回一个文件的输入流.
  • String getRealPath(String path); --- 返回一个路径的磁盘绝对路径.

使用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);        }使用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);        }
总结:ServletContxt的功能:【功能一:读取全局初始化参数】String getInitParameter(String name)Enumeration getInitParameterNames()
配置全局初始化参数:
<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的类型】String getMimeType(String file) 获得文件的MIME类型
代码实现:
/**         * 获得文件的MIME的类型         */        private void test2() {                String type = this.getServletContext().getMimeType("1.html");                System.out.println(type);        }【功能三:作为域对象存取数据】
  • 范围:整个web项目.而且全局的对象.
  • 创建:服务器启动的时候,服务器为每个web项目创建一个单独的ServletContext对象.
  • 销毁:服务器关闭的时候销毁ServletContext.

【功能四:读取web项目下的文件】类加载器读取文件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);        }登录成功后,完成文件的下载
在登录成功后,页面跳转文件下载的列表的页面,点击列表中的某些连接,下载文件.
Response的概述
  • Response:代表响应的对象,从服务器向浏览器输入内容
Response的常用API
  • 响应行
    • void setStatus(int sc)设置状态码
  • 响应头:
针对一个key对应多个value的头信息.
void addDateHeader(String name,long date)
void addHeader(String name,String value)
void addIntHeader(String name,int value)
针对一个key对应一个value的头信息.
void setDateHeader(String name,long date)
void setHeader(String name,String value)
void setIntHeader(String name,int value)
  • 响应体
ServletOutputStream getOutputStream()
PrintWriter getWriter()
【文件下载的方式】
  • 一种:超链接下载.直接将文件的路径写到超链接的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 = 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);        }}文件下载的核心思想:
IO的读/写
InputStream in = new FileInputStream("服务器上的路径");
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();中文文件的下载
  • 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);        }}response输出响应内容的方法
向页面响应的方法:
  • getOutputStream();
  • getWriter();
  • 这两个方法是互斥的.
    • 做出响应的时候只能使用其中的一种流响应.

使用字符流输出中文:
  • 有没有乱码?为什么?
    • 一定会乱码,response使用的字符流有缓冲区的.
    • response的字符流的缓冲区的默认编码是ISO - 8859 -1,编码根本不支持中文

输出中文乱码的处理:
  • 字节流:
    • 设置浏览器默认打开的编码:
      • 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”);
完成用户注册的功能
网站首页上点击注册的链接,跳转到注册页面,在注册页面中输入信息.完成注册:(将数据保存到数据库中).
Request的概述
Request 代表用户的请求.
Request的API
功能一:获得客户机相关的信息
  • 获得请求方式:
    • String getMethod()
  • 获得请求的路径:
    • String getRequestURI()
    • StringBuffer getRequestURL()
  • 获得客户机相关的信息:
    • String getRemoteAddr()
  • 获得工程名:
    • String getContextPath()

功能二:获得从页面提交的参数:
  • String getParameter(String name)
  • Map getParameterMap()
  • Enumeration getParameterNames()
  • String[] getParameterValues(String name)
功能三:作为域对象存取数据:
  • void removeAttribute(String name)
  • void setAttribute(String name,Object o)
  • Object getAttribute(String name)
演示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);        }}代码实现
  • 步骤一:创建数据库和表
  • 步骤二:创建包和类
  • 步骤三:引入注册页面.
  • 步骤四:注册代码的实现
处理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的构造方法:
    • String(byte[] bytes.String charsetName) 通过使用指定的charset解码指定的byte数组,构造一个新的String .

Request作为域对象存取数据
使用request对象存取数据:
  • setAttribute(String name,String value);
  • Object getAttribute(String name);
request的作用范围:
  • 作用范围就是一次请求的范围.
  • 创建和销毁:
    • 创建:客户端向服务器发送了一次请求以后,服务器就会创建一个request的对象.
    • 销毁:当服务器对这次请求做出了响应之后.

重定向和转发的区别:(redirect和forward的区别)
  • 重定向的地址栏会发生变化,转发的地址栏不变.
  • 重定向两次请求两次响应,转发一次请求一次响应.
  • 重定向路径需要加工程名,转发的路径不需要加工程名.
  • 重定向可以跳转到任意网站,转发只能在服务器的内部进行转发.

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马