• 理解Servlet及其对象


    一.ServeltConfig对象

      在Servlet的配置文件中,可以使用一个或多个<init-param>标签为Servlet配置一些初始化参数。而不当Servlet配置了初始化参数后,web容器在创建Servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在Servlet的init方法时,将ServleConfig对象传递给Servlet。

      在开发程序中,可以通过ServletConfig对象得到当前Servlet初始化的参数信息。

      具体方法如下:

      在web应用下配置web.xml文件

       

     <servlet>
    
        <servlet-name>Demo1</servlet-name>
    
        <servlet-class>cn.itcast.web.servlet.Demo1</servlet-class>
    
        <init-param>
    
                  <param-name>encoding</param-name>         
    
               <param-value>UTF-8</param-value>
    
        </init-param>
    
        <init-param>
    
                  <param-name>driver</param-name>       
    
               <param-value>com.mysql.jdbc.Driver</param-value>
    
        </init-param>
    
        <init-param>
    
                  <param-name>url</param-name>   
    
               <param-value>jdbc:mysql://127.0.0.1:3306/test</param-value>
    
        </init-param>
    
        <init-param>
    
                  <param-name>username</param-name>         
    
               <param-value>root</param-value>
    
        </init-param>
    
        <init-param>
    
                  <param-name>password</param-name>        
    
               <param-value>root</param-value>
    
        </init-param>
    
        <load-on-startup>1</load-on-startup>
    
       </servlet>

    实现方法:

        

    public void doGet(HttpServletRequest request, HttpServletResponse response)throws
    
    ServletException, IOException {
    
                  ServletConfig config = this.getServletConfig();
    
                  String driver = config.getInitParameter("driver");
    
                  String url = config.getInitParameter("url");
    
                  String username = config.getInitParameter("username");
    
                  String password = config.getInitParameter("password");
    
                  if(driver!=null && url!=null && username!=null && password!=null){
    
                         System.out.println("driver="+driver);
    
                         System.out.println("url="+url);
    
                         System.out.println("username="+username);
    
                         System.out.println("password="+password);
    
                  }
    
           }

    ServletConfig对象的作用:

      1)获取字符集编码(中文)

      2)获得数据库连接的信息

      3)获取配置文件,查看struts案例的web.xml文件

    ServletContext 是配置Servlet环境变量的类。

    当工程部署时,就创建了ServletContext对象,同一个工程中的ServletDemo类都共享同一个

    二、ServletContext对象

    ServletContext对象在web服务器停止或web应用重新部署时,原有的ServletContext对象被销毁。

    如何获取ServletContext对象?

    1)ServletContext context = this.getServletContext();

    2)ServletContext context = this.getServletConfig().getServletContext();

    3)ServletContest context = request.getSession().getServletContext();

    获取Servlet中的配置参数,则使用到的Servlet对象为ServletConfig

    获取WEB应用中的配置参数,则使用到的Servlet对象为ServletContext

    在Servlet开发中,需要加载文件,则需要使用SevletContext对象。

    代码如下:

    Public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    
                  //传统方法是基于tomcat/bin/目录下
    
                  //BufferedReader br = new BufferedReader(new FileReader("src/config.txt"));
    
                  //System.out.println(br.readLine());
    
                  //br.close();
    
                  ServletContext context = this.getServletContext();
    
                  InputStream is = context.getResourceAsStream("/config.properties");//斜杠表示当前web应用工程下,即day06工作
    
                  Properties props = new Properties();
    
                  props.load(is);
    
                  String email = props.getProperty("email");
    
                  response.getOutputStream().write(email.getBytes());
    
           }
     

    扩展知识1

    在Servlet开发中,除了使用ServletContext对象加载项目中需要的资源文件外(如.xml文件、.properties文件),还可以通过类加载器加载或读取文件,使用此方法,需要注意以下几个方面:

    1. 代码如下:
      InputStream is = Demo6.class.getClassLoader().getResourceAsStream("config.properties");

      “confing.properites”是类路径,路径与Class.forName("cn.itcast.web.servlet.Demo1")相似,以/分隔。

    1. 有具只能加载类路径下的资源;
    2. 文件位置只能位于类路径下,即IDE工具的src/目录下;
    3. 将整个文件,无论多在,加载到内存;

    扩展知识2

    关于路径的问题:

    1. 客户端:以浏览器发送请求为基础,例如:<form action=""/>或<a href=""/>或response.sendRedirect("/day06/fail.html");都以/开头,这里/表示"webapps"目录;
    2. 服务端:以服务器内部转发为基本,浏览器不可见。

                   这里/表示"当前web应用"的目录,即day06。

    Servlet开发中转发代码:

    //转发到success.html页面
    
    ServletContext context = this.getServletContext();
    
                         //取得转发对象
    
                         RequestDispatcher rd = context.getRequestDispatcher("/success.html");
    
                         //真实转发
    
                         rd.forward(request,response);
    
    或者:
    
    RequesttDispatcher rd = this.getServletContext.getRequsetDispatcher.forward(request,response);
     

    扩展知识3

      设置缓存问题及乱码问题:

    1)浏览器默认有缓存,但缓存内容无期,对于刷新直接向服务端请求资源。

         response.setDateHeader("expires",end);

       2)高级缓存[304]

       3)Servlet开发中,解决中文乱码问题:

    使用代码: response.setContentType(“text/html”,”charset=UTF-8”);

         或者:response.setHeader(“content-type”,”text/html;charset=UTF-8”);

    下载中文名文件,代码如下:

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    
               throws ServletException, IOException {
    
           ServletContext context = this.getServletContext();
    
           String path = context.getRealPath("/爱.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();
    
        }
    
     

    三、 response对象

    1)   response向浏览器输出信息,字符方式或字节方式输出问题

    要么使用字节方式输出:

      response.getOutputStream().write(“你好!”.getBytes) ;

    要么使用字符方式输出:

      Response.getWriter().write(“你好!”);

    2)  对于response输出,内存和响应头一同输出到浏览器

         即将response.setContentType(“text/html”,”charset=UTF-8”);设置完成后,会一直在整个的response对象中存在,不需要再设置。

     3)      在response对象中,使用到一些流操作的时候,可以不用关闭流,这时web服务器在销毁response之前,会自动将所涉及的流关闭。

    例如:PrintWriter pw = response.getWriter();

          pw.write(“你好!”);

       //  pw.flush();  不需要写这两句

       //  pw.close();

    四、             request对象

       1) request对象主要是获取客户端信息时使用的,例如获取客户端form表单信息、IP地址、主机名、web服务器的IP地址等信息。

    如下代码:

       String clientIP = request.getRemoteAddr();

       String ServiceIP = request.getLocalAddr();

       System.out.println(“clientIP=”+clientIP);

       System.out.println(“ServiceIP=”+ServiceIP);

       2)  request对象可以获取浏览器请求头信息

        String accept  = request.getHeader(“accept-encoding”);

        String host = request.getHeader(“Host”);

    3)  request对象最重要的方法是获取参数信息

     例如:获取表单中的参数信息

    <form ation=”ServletDemo” method = “post”>

    用户名:<input type = “text”  name=”username “/>

    密码:  <input type = “text”  name=”password “/>

    <input  type = “submit” value = “提交”/>
    </form>

    代码如下:

        String username = request.getParameter(“username”);

        String password = request.getParameter(“password”);

    4)request细节

      1)如果在forward()之前已经向浏览器输出内容,并且关闭了流对象此时forword()代码转发到的那个页面的代码不执行

       如下代码:

       PrintWriter pw = response.getOutputStream();

       pw.write("aaa");

       pw.flush();//

       pw.close();//关闭了流对象

       request.getRequestDispach().forward(request,response); 

      2)如果在forward()之前已经向浏览器输出内容,没有关闭流对象,但是输出到缓存中,此时forward()代码转发到的那个页面代码会执行,原来输出到缓存的代码不执行,即忽略。

      3)如果在forward()之后向浏览器输出内容,忽略。

      4)如果在forward()之前写的响应头会保留。即只要在Servlet中设置了一处响应头,

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

       在request转发或者转发之后都不需要重新设置

    4)使用request对象进行转发

      代码如下:

    request.getRequestDispatcher(“/success.html”).forward(request,response) ;

    //注意:这里的”/”代表day06

    5)获取请求参数

    //浏览器地址栏只有一个请求参数时,则使用

    String username = request.getParameter(“username”);

    //浏览器地址栏中有一个请求参数但有多个不同的值时,则使用

    String[] liles = request.getParameterValues(“likes”);

    For(String like:lies){

       System.out.println(like);

    }

    //浏览器地址栏中有多个请求参数不同值时,则使用

    Enumeration enums = request.getParameterNames();

    While(enmus.hasMoreElements()){

       String key = (String) enums.nextElement();

       System.out.println(key);

    }

    扩展知识:

    实现网站中的防盗链问题

    五、重定向和转发区别?

    1)重定向可以在不同的web应用中导航,但转发仅限于当前web应用中导航。

    2)重定向中的/表示webapps目录,即tomcat中web应用的根目录,而转发中的/表示当前的web应用,即day07。

    3)重定向地址栏会变化,而转发地址栏不会变化。

    4)重定向会通知浏览器,但转发是服务器内部行为,项目中,以减少HTTP请求为原则,尽可能使用转发。

    5)重定向不会共享request域对象,但转发可以共享request域对象。

     注意:HttpServletRequest有二层含义:

    1. 表示客户端向服务端的请求
    2. 表示request容器/对象/域对象(set/getAttribute())

         常用的方法:

    Request.getParameter(String str);//请求体的参数信息

    Request.getParameterValues(String []);

    Request.getParameterNames(Enumeration enums);

    Request.getHeader();//请求头中的参数信息

    Request.set/getAttribute();//从域对象中设置/获取对应的信息

    六、 Request.getRequestDispach(“”).forword(request,response)

    与request.getRequestDispach(“”).include(request,response)区别

    使用include进入转发时,页面会包含其它的web资源(html/jsp/servlet),include代码转发到的那个页面执行完代码后,会返回到原来包含include代码页面继续执行它下面的代码。而forword()刚好相反。

    注意:

    Request.getMethod();//获取客户端以什么方式提交(GET/POST方式)

    Request.getContextPath();//获取当前web应用名(/day07)

  • 相关阅读:
    UVA1401 Remember the word DP+Trie
    LG5202 「USACO2019JAN」Redistricting 动态规划+堆/单调队列优化
    模拟赛总结合集
    LG5201 「USACO2019JAN」Shortcut 最短路树
    LG5200 「USACO2019JAN」Sleepy Cow Sorting 树状数组
    LG5196 「USACO2019JAN」Cow Poetry 背包+乘法原理
    20190922 「HZOJ NOIP2019 Round #7」20190922模拟
    LG2530 「SHOI2001」化工厂装箱员 高维DP+记忆化搜索
    LG2893/POJ3666 「USACO2008FEB」Making the Grade 线性DP+决策集优化
    关于对QQ 输入法的评价
  • 原文地址:https://www.cnblogs.com/luihengk/p/3727167.html
Copyright © 2020-2023  润新知