• ServletContext对象


    **1 ServletContext对象
      1)在web应用中,由服务器创建的唯一的一个对象是ServletContext
      2)ServletContext对象在每一个Servlet中取得都是相同到
      3)ServletContext对象在存取方法:
        存ServletContext.setAttribute(String,Object):void
        取ServletContext.getAttribute(String):Object

    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * http://192.168.10.252:8080/day06/Demo11?username=jack回车
     */
    
    public class Demo11 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            
            //取得客户端的请求参数
            String username = request.getParameter("username");
            
            //取得唯一的一个ServletContext对象
            ServletContext context = this.getServletContext();
            System.out.println("Demo11:"+context.hashCode());
            
            //将信息存入ServletContext对象
            context.setAttribute("USERNAME",username);
        }
    }
    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * http://192.168.10.252:8080/day06/Demo12回车
     */
    
    public class Demo12 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            
            //取得唯一的一个ServletContext对象
            ServletContext context = this.getServletContext();
            System.out.println("Demo12:"+context.hashCode());
            
            //根据name取得ServletContext对象中的值
            String username = (String) context.getAttribute("USERNAME");
            
            //在浏览器中输出
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("用户名:" + username + "<br/>");
            
        }
    }

      4)在web应用中,可以取得web应用的初始化参数

    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo2 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String email = context.getInitParameter("email");
            String tel = context.getInitParameter("tel");
            if(email!=null && tel!=null){
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().write("赵老师邮箱:" + email + "<br/>");
                response.getWriter().write("赵老师电话:" + tel + "<br/>");
            }
        }
    }
    <context-param>
          <param-name>email</param-name>
          <param-value>runsin0723@163.com</param-value>
      </context-param>    
      <context-param>
          <param-name>tel</param-name>
          <param-value>13632334557</param-value>
      </context-param>

      5)ServletContxt对象能够实现转发功能,即307+location

        ServletContext context = this.getServletContext();
        //定位需要转发的路径
        RequestDispatcher rd = context.getRequestDispatcher("/success.html");
        //真正转向页面
        rd.forward(request,response);

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>login.html</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      </head>
      <body>
          <form 
              action="/day06/LoginServlet" 
              method="post">
              <table border="1" align="center">
                  <caption>用户登录[模拟MVC]</caption>
                  <tr>
                      <th>用户名</th>
                      <td><input type="text" name="username"/></td>
                  </tr>
                  <tr>
                      <th>密码</th>
                      <td><input type="password" name="password"/></td>
                  </tr>
                  <tr>
                      <th>验证码</th>
                      <td>
                          <input type="text" name="checkCode"/>
                      </td>
                      <td>
                          <img src="/day06/Demo3"/>
                      </td>
                  </tr>
                  <tr>
                      <td colspan="2" align="center">
                          <input type="submit" value="提交"/>
                      </td>
                  </tr>
              </table>
          </form>
      </body>
    </html>
    package cn.itcast.web.servlet;
    
    public class LoginBean {
        public boolean validate(String username){
            boolean flag = false;
            if(username!=null && "jack".equals(username)){
                flag = true;
            }
            return flag;
        }
    }
    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoginServlet extends HttpServlet {
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            
            //取得表单提交的参数
            String username = request.getParameter("username");
            
            //调用模型层对象
            LoginBean loginBean = new LoginBean();
            boolean flag = loginBean.validate(username);
            
            //根据返回值,转发到不同的页面
            if(flag){
                ServletContext context = this.getServletContext();
                //定位需要转发的路径
                RequestDispatcher rd = context.getRequestDispatcher("/success.html");
                //真正转向页面
                rd.forward(request,response);
            }else{
                ServletContext context = this.getServletContext();
                //定位需要转发的路径
                RequestDispatcher rd = context.getRequestDispatcher("/fail.html");
                //真正转向页面
                rd.forward(request,response);
            }
        }
    }

       6)如果以传统方式读取资源文件(txt/xml/properties),是相对于web服务器的bin/目录而言

    *7)如果以ServletContext方式读取资源文件(txt/xml/properties),是相对于web服务器的当前web应用目录而言
        此时/表示:当前web应用,即day06
    *8)类加载器只能加载IDE工具下src目录下的资源文件,其它目录无法加载
        此时/表示:/WEB-INF/classes/目录

    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo4 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            
            /*传统方式
            InputStream is = new FileInputStream("src/config.properties");
            Properties props = new Properties();
            props.load(is);
            System.out.println(props.getProperty("email"));
            */
            
            ServletContext context = this.getServletContext();
            InputStream is = context.getResourceAsStream("/doc/config.properties");
            Properties props = new Properties();
            props.load(is);
            System.out.println(props.getProperty("email"));
            
        }
    }
    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo5 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            //取得当前对象的字节码对象
            Class clazz = this.getClass();
            //取得当前对象的类加载器
            ClassLoader cl = clazz.getClassLoader();
            //通过类加载器加载资源文件
            InputStream is = cl.getResourceAsStream("/cn/itcast/web/config/config.properties");
            Properties props = new Properties();
            props.load(is);
            System.out.println(props.getProperty("email"));
        }
    }

    10)其实浏览器访问的静态资源,本质上是由一个缺省的Servlet来帮你处理的

    package cn.itcast.web.servlet;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class DownServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            //NO1获取当前config文件的方式
            ServletConfig config = this.getServletConfig();
            String filePath = config.getInitParameter("filePath");
            //NO2
            File file = new File(filePath);
            response.setHeader("content-disposition","attachment;filename="+file.getName());
            //NO3
            InputStream is = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while((len=is.read(buf))>0){
                os.write(buf,0,len);
            }
            is.close();
            os.close();
        }
    }

    2 关于路径的问题
      1)二种加载方式的区别?
        服务端   
        ServletContext方式:
        1)资源的文件的位置任意 
        2)加载文件时,只会以流的方式读取,不会一次性加载全部 
        3)/表示当前web应用,即day06

        类加载器方式:
        1)资源文件的位置只能放置类路径下,即IDE工具的src目录下 
        2)加载文件时,会一次性加载全部文件 
        3)/表示当前/WEB-INF/classes/ 
       2)有关/的问题?
         物理硬盘路径使用[window系统]
         网络路径使用/
         如果/表示客户端路径的话,表示tomcat/webapps/目录  
    *3 缓存应用
       1)对于浏览器的刷新而言,当浏览器缓存中有资源,也会找服务端要资源,只有在回车访问情况下,才找缓存.对于不经常变化的数据,在servlet中可以为其设置合理的缓存时间值,以避免浏览器频繁向服务器发送请求,提升服务器的性能。
       2)如果要实现一种高级功能,即客户端请求动态web资源时,动态web资源发现发给客户端的数据更新了,就给客户端发送最新的数据,如果发现数据没有更新,则动态web资源就要客户端就去访问它自己缓存的数据。此种情况可以通过覆写动态web资源(即servlet)的getLastModify方法予以实现。

    package cn.itcast.web.servlet;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /*
     * http://localhost:8080/day06/login.html回车
     * 设置静态资源[html/css/js]缓存的时间[做成一个缺省的的Servlet,路径为/]
     */
    
    public class Demo6 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            String uri = request.getRequestURI();
            //如果是一个html静态资源
            if(uri!=null && uri.endsWith("html")){
                String html = this.getServletConfig().getInitParameter("html");
                if(html!=null){
                    long end = Long.parseLong(html)*1000 + System.currentTimeMillis();
                    response.setDateHeader("expires",end);
                }
            }
        }
    }
    <servlet>
        <servlet-name>Demo6</servlet-name>
        <servlet-class>cn.itcast.web.servlet.Demo6</servlet-class>
        <init-param>
            <param-name>html</param-name>
            <param-value>86400</param-value>
        </init-param>
        <init-param>
            <param-name>css</param-name>
            <param-value>123456</param-value>
        </init-param>
        <init-param>
            <param-name>js</param-name>
            <param-value>654321</param-value>
        </init-param>
      </servlet>
    package cn.itcast.web.servlet;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    //缓存高级应用
    public class Demo7 extends HttpServlet {
        protected long getLastModified(HttpServletRequest req) {
            System.out.println("getLastModified()");
            String path = this.getServletContext().getRealPath("/doc/abc.txt");
            File file = new File(path);
            return file.lastModified();
        }
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            System.out.println("doGet()");
            ServletContext context = this.getServletContext();
            InputStream is = context.getResourceAsStream("/doc/abc.txt");
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while((len=is.read(buf))>0){
                os.write(buf,0,len);
            }
            is.close();
            os.close();
        }
    }

    *4 response的应用
      1)web容器会传入与web容器相关的HttpServletRequest和HttpServletResponse对象的实现。request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。
      2)每次浏览器请求,web容器会创建新的请求和响应对象,这二个对象的生命周期仅限于web容器内。HttpServletResponse对象服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
      3)对于字节方式来说,输出数字,respnse会编查ISO8859-1编码表,将码表的中的数字对应的字符取出来显示,即遇数字转字符
      4)如果要输出数字,提前将数字转化成字符串
      5)对于字符方式来说,可以直接输出数字
      6)将中文转成字节数组时,查UTF-8码表,如果不写的话,默认查ISO8859-1码表 
      7)以字符方式输出中文,提前设置编码方式;以字节方式输出中文,提前设置转化编码方式
        字符:   
        response.getOutputStream().write("中国".getBytes("UTF-8"));
        字节:
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("美国");
       8)HTML中的所有<meta/>标签,类似于response.setHeader(),目的是通知浏览器以特定的方式显示页面的信息
       9)重定向是客户端和服务端的共同行为,
         response.sendRedirect("/day06/message.html")其中/表示webapps目录

       10)response常见应用:

          •向客户端输出中文数据

          •分别以OutputStream和PrintWriter输出

          •用OutputStream输出1,客户端看到的是什么?

          •中文名文件下载

          •生成随机图片

          •发送http头,控制浏览器定时刷新网页(refresh)

          •发送http头,控制浏览器禁止缓存当前文档内容

          •多学一招:使用HTML/JSP语言里面的<meta>标签来控制浏览器行为<meta http-equiv="content-type" content="text/html; charset=UTF-8">

          •通过response实现请求重定向。

          •请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。

          •应用场景:用户登陆。

          •实现方式

          •response.sendRedirect(“/welcome.html”)

          •实现原理:

              302状态码和location头即可实现重定向

    package cn.itcast.web.response;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    //向浏览器输出中文数据 
    public class Demo1 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            //以字节方式输出
             //response.getOutputStream().write((97+"").getBytes());
            //以字符方式输出
             //response.getWriter().write(65);
            //response.getOutputStream().write("中国".getBytes("UTF-8"));
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write("美国");
        }
    }
    package cn.itcast.web.response;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    //中文名文件下载
    public class Demo2 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            String path = context.getRealPath("/images/神奇的图片.JPG");
            File file = new File(path); 
            response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(file.getName(),"UTF-8"));
            InputStream is = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while((len=is.read(buf))>0){
                os.write(buf,0,len);
            }
            is.close();
            os.close();
        }
    }
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>download.html</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      </head>
      <body>    
          <a href="/day06/Demo2">下载中文文件</a>
      </body>
    </html>
    package cn.itcast.web.response;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    import java.util.UUID;
    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 Demo3 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            response.setHeader("expires","-1");
            response.setHeader("cache-control","no-cache");
            response.setHeader("pragma","no-cache");
            //以内存中构造一副图片
            BufferedImage image = new BufferedImage(80,25,BufferedImage.TYPE_INT_RGB);
            //取得画笔
            Graphics g = image.getGraphics();
            //设置字体大小和颜色
            g.setColor(Color.YELLOW);
            g.setFont(new Font("黑体",Font.BOLD,22));
            //在图片中,画一个字符串"1A2B"
            g.drawString(getString(),20,20);
            //将内存中的图片以JPG格式输出到浏览器
            ImageIO.write(image,"JPG",response.getOutputStream());
        }
        //产生一个随机字符串
        private String getString(){
            String str = "";
            String numberAndLetter="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
            int length = numberAndLetter.length();
            for(int i=1;i<=4;i++){
                if(i==1 || i==3){//数字
                    while(true){
                        Random random = new Random();
                        int index = random.nextInt(length);
                        String value = numberAndLetter.substring(index,index+1);
                        if(value.matches("[0-9]")){
                            str += value;
                            break;
                        }
                    }
                }else if(i==2 || i==4){//大小字母
                    while(true){
                        Random random = new Random();
                        int index = random.nextInt(length);
                        String value = numberAndLetter.substring(index,index+1);
                        if(value.matches("[A-Za-z]")){
                            str += value;
                            break;
                        }
                    }
                }
            }
            return str;
        }
    }
    package cn.itcast.web.response;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoginServlet extends HttpServlet {
        public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            String checkCode = request.getParameter("checkCode");
            System.out.println("用户名:" + username);
            System.out.println("密码:" + password);
            System.out.println("验证码:" + checkCode);
            //重定向到message.html页面
            //这时/表示webapps目录
            response.sendRedirect("/day06/message.html");
        }
    }

    5 response细节
      1)以字符或字节方式输出内容的话,只能使用其中一种
      2)响应头会以叠加的方式设置,在相同的情况下,后者起决定作用

    package cn.itcast.web.response;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Demo4 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
            response.setContentType("text/html;charset=UTF-8");
            response.setContentType("text/html;charset=GBK");
            PrintWriter pw = response.getWriter();
            pw.write("美国");
            pw.flush();
            pw.close();
        }
    }

       3)在没有关闭流的情况下,web容器帮你自动关闭所有从response中取得IO流

      4)getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。

      5)getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

      6)Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。

      7)Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。

  • 相关阅读:
    作业 20180918-2 每周例行报告
    将Python文件打包为exe文件,并在控制台运行之简易教程
    作业20181011-1 每周例行报告
    用WebView加载本地图片的方法
    ios webview自适应实际内容高度4种方法
    UIWebView加载本地网页与图片的方法
    nonatomic与atomic的区别与作用
    @dynamic与@synthesize的区别与用法
    xib与storyboard的区别
    iOS与H5的交互
  • 原文地址:https://www.cnblogs.com/sunhan/p/3542146.html
Copyright © 2020-2023  润新知