zoukankan      html  css  js  c++  java
  • Java Web开发总结(一)

    1、如何解决 tomcat 中文乱码问题?

    2、如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet

     <!-- 将ServletDemo2配置成缺省Servlet -->
      <servlet-mapping>
        <servlet-name>ServletDemo2</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>

     3、Servlet 线程安全:当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

        3.1通过ServletContext获取web资源的绝对路径

        String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/config/db3.properties");

    4、ServletContext对象

           WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用
      ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
      由于同一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象

    
    
    ServletContext context = this.getServletConfig().getServletContext();//获得ServletContext对象
    context.setAttribute("data", data);  //将data存储到ServletContext对象
    在另一个 servlet 中:
    
    
    String data = (String) context.getAttribute("data");//从ServletContext对象中取出数据
    
    

    5、获取WEB应用的初始化参数

    在web.xml文件中使用<context-param>标签配置WEB应用的初始化参数
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
        <display-name></display-name>
        <!-- 配置WEB应用的初始化参数 -->
        <context-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/test</param-value>
        </context-param>
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

     

    servlet 中 获取Web应用的初始化参数:

    
    
    ServletContext context = this.getServletContext();
    //获取整个web站点的初始化参数
    String contextInitParam = context.getInitParameter("url");
    
    

    6、页面跳转  用servletContext实现请求转发

    (6.1)Request对象实现请求转发

            A、通过 ServletContext 的 getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。 

    
    
    ServletContext context = this.getServletContext();//获取ServletContext对象
    RequestDispatcher rd = context.getRequestDispatcher("/servlet/ServletContextDemo5");//获取请求转发对象(RequestDispatcher)
    rd.forward(request, response);//调用forward方法实现请求转发
     
    RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp");
    reqDispatcher.forward(request, response);
    
    

        B:2、通过request 对象提供的 getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。

    request.getRequestDispatcher("/test.jsp").forward(request, response);
    <body>
          使用普通方式取出存储在request对象中的数据:
          <h3 style="color:red;"><%=(String)request.getAttribute("data")%></h3>
         使用EL表达式取出存储在request对象中的数据:
         <h3 style="color:red;">${data}</h3>
      </body>

     2、通过response实现请求重定向

     /**
             * 1.调用sendRedirect方法实现请求重定向,
             * sendRedirect方法内部调用了
             * response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
             * response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
             */
            response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
            
            //2.使用response设置302状态码和设置location响应头实现重定向实现请求重定向
            //response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
            //response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
    
    

     7、利用ServletContext对象读取资源文件

    注意:通过类装载器读取资源文件的注意事项:不适合装载大文件,否则会导致jvm内存溢出
    (1.1)使用类装载器读取资源文件【用类装载器读取src目录下的db1.properties配置文件】
      private void readPropFile(HttpServletResponse response) throws IOException {
            //获取到装载当前类的类装载器
            ClassLoader loader = ServletContextDemo7.class.getClassLoader();
            //用类装载器读取src目录下的db1.properties配置文件
            InputStream in = loader.getResourceAsStream("db1.properties");
            Properties prop = new Properties();
            prop.load(in);
            String driver = prop.getProperty("driver");
            String url = prop.getProperty("url");
            String username = prop.getProperty("username");
            String password = prop.getProperty("password");
            response.getWriter().println("用类装载器读取src目录下的db1.properties配置文件:");
            response.getWriter().println(
                    MessageFormat.format(
                            "driver={0},url={1},username={2},password={3}", 
                            driver,url, username, password));
        }

     (1.2)读取类路径下面、包下面的资源文件

    //获取到装载当前类的类装载器
            ClassLoader loader = ServletContextDemo7.class.getClassLoader();
            //用类装载器读取src目录下的gacl.servlet.study包中的db4.properties配置文件
            InputStream in = loader.getResourceAsStream("gacl/servlet/study/db4.properties");
            Properties prop = new Properties();
            prop.load(in);
            String driver = prop.getProperty("driver");
            String url = prop.getProperty("url");
            String username = prop.getProperty("username");
            String password = prop.getProperty("password");
            response.getWriter().println("用类装载器读取src目录下的gacl.servlet.study包中的db4.properties配置文件:");
            response.getWriter().println(
                    MessageFormat.format(
                            "driver={0},url={1},username={2},password={3}", 
                            driver,url, username, password));
        }

     

    (2)//读取src目录下的db.config包中的配置文件
     /**
         * 通过ServletContext对象读取src目录下的properties配置文件
         * @param response
         * @throws IOException
         */
        private void readSrcDirPropCfgFile(HttpServletResponse response) throws IOException {
            /**
             * 通过ServletContext对象读取src目录下的db1.properties配置文件
             */
            InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db1.properties");
            Properties prop = new Properties();
            prop.load(in);
            String driver = prop.getProperty("driver");
            String url = prop.getProperty("url");
            String username = prop.getProperty("username");
            String password = prop.getProperty("password");
            response.getWriter().println("读取src目录下的db1.properties配置文件:");
            response.getWriter().println(
                    MessageFormat.format(
                            "driver={0},url={1},username={2},password={3}", 
                            driver,url, username, password));
        }

     

    (3)读取 src 下某个包中的配置文件【读取src目录下的gacl.servlet.study包中的db4.properties配置文件】
    private void readPropCfgFile2(HttpServletResponse response)
                throws IOException {
            InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/gacl/servlet/study/db4.properties");
            Properties prop = new Properties();
            prop.load(in);
            String driver = prop.getProperty("driver");
            String url = prop.getProperty("url");
            String username = prop.getProperty("username");
            String password = prop.getProperty("password");
            response.getWriter().println("读取src目录下的gacl.servlet.study包中的db4.properties配置文件:");
            response.getWriter().println(
                    MessageFormat.format(
                            "driver={0},url={1},username={2},password={3}", 
                            driver,url, username, password));
        }
    
    

     (4)读取src目录下的db.config包中的db3.properties配置文件

    //通过ServletContext获取web资源的绝对路径
            String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/config/db3.properties");
            InputStream in = new FileInputStream(path);
            Properties prop = new Properties();
            prop.load(in);
            String driver = prop.getProperty("driver");
            String url = prop.getProperty("url");
            String username = prop.getProperty("username");
            String password = prop.getProperty("password");
            response.getWriter().println("读取src目录下的db.config包中的db3.properties配置文件:");
            response.getWriter().println(
                    MessageFormat.format(
                            "driver={0},url={1},username={2},password={3}", 
                            driver,url, username, password));
        }
    
    

     (5)通过ServletContext对象读取WebRoot目录下的properties配置文件

     /**
             * 通过ServletContext对象读取WebRoot目录下的properties配置文件
             * “/”代表的是项目根目录
             */
    InputStream in = this.getServletContext().getResourceAsStream("/db2.properties"); Properties prop = new Properties(); prop.load(in); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String username = prop.getProperty("username"); String password = prop.getProperty("password"); response.getWriter().println("读取WebRoot目录下的db2.properties配置文件:"); response.getWriter().print( MessageFormat.format( "driver={0},url={1},username={2},password={3}", driver,url, username, password)); }

     8、向浏览器输出中文数据

    (1)response.getOutputStream() :得到输出 二进制数据 的 ServletOuputStream对象。

    (2)response.getWriter()方法:得到、输出文本数据Printwriter对象。

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

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

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

    (8.1)以浏览器输出 binary data,字节流方式,需使用  OutputStream

    在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开。

    比如:outputStream.write("中国".getBytes("UTF-8"));其意思是:使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出;此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码。

    那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?

    (1)可以通过设置响应头控制浏览器的行为,例如:response.setHeader("content-type", "text/html;charset=UTF-8");其意思是:通过设置响应头控制浏览器以UTF-8的编码显示数据。

    String data = "中国";
    OutputStream outputStream = response.getOutputStream();//获取OutputStream输出流
    //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
    response.setHeader("content-type", "text/html;charset=UTF-8");
    byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
        /**
             * data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,
             * 如果是中文的操作系统环境,默认就是查找查GB2312的码表,
             * 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字
             * 比如: "中"在GB2312的码表上对应的数字是98
             *         "国"在GB2312的码表上对应的数字是99
             */
            /**
    //getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表
    outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组

    (8.2)使用PrintWriter流向客户端浏览器输出中文数据,字符流方式, character text

          使用PrintWriter流输出中文注意问题:

      在获取PrintWriter输出流之前 首先使用 "response.setCharacterEncoding(charset)" 设置字符以什么样的编码输出到浏览器

    如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,

    然后再使用 response.getWriter(); 获取PrintWriter输出流,这两个步骤不能颠倒,如下:

    response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
    /**
    * PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
    * 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
    */
    PrintWriter out = response.getWriter();//获取PrintWriter输出流

    然后再使用 response.setHeader("content-type", "text/html;charset=字符编码");设置响应头,控制浏览器以指定的字符编码编码进行显示,例如:

    response.setHeader("content-type", "text/html;charset=UTF-8");
    //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
    /**
    * 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为
     *response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
    * 等同于response.setHeader("content-type", "text/html;charset=UTF-8");
    */
    response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");

    具体实例:

    public void outputChineseByPrintWriter(HttpServletResponse response) throws IOException{
            String data = "中国";
            
            //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
            //response.setHeader("content-type", "text/html;charset=UTF-8");
            
            response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
            /**
             * PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
             * 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
             */
            PrintWriter out = response.getWriter();//获取PrintWriter输出流
            /**
             * 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为
             * out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
             * 等同于response.setHeader("content-type", "text/html;charset=UTF-8");
             */
            out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
            out.write(data);//使用PrintWriter流向客户端输出字符
        }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }

     9、response 文件下载

    文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载

    文件下载功能的实现思路:

    1.   获取要下载的文件的绝对路径
    2.   获取要下载的文件名
    3.   设置 content-disposition 响应头控制浏览器以下载的形式打开文件
    4.   获取要下载的文件输入流
    5.   创建数据缓冲区
    6.   通过 response 对象获取 OutputStream 流
    7.   将 FileInputStream 流写入到 buffer 缓冲区
    8.   使用 OutputStream 将缓冲区的数据输出到客户端浏览器
      /**
           * 下载文件,通过OutputStream流
           * @param response
           * @throws FileNotFoundException
           * @throws IOException
           */
          private void downloadFileByOutputStream(HttpServletResponse response)
                  throws FileNotFoundException, IOException {
              //1.获取要下载的文件的绝对路径
              String realPath = this.getServletContext().getRealPath("/download/1.JPG");
              //2.获取要下载的文件名
              String fileName = realPath.substring(realPath.lastIndexOf("\")+1);
              //3.设置content-disposition响应头控制浏览器以下载的形式打开文件
              response.setHeader("content-disposition", "attachment;filename="+fileName);
      //需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),否则会出现文件名乱码。
              response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
      //4.获取要下载的文件输入流 InputStream in = new FileInputStream(realPath); int len = 0; //5.创建数据缓冲区 byte[] buffer = new byte[1024]; //6.通过response对象获取OutputStream流 OutputStream out = response.getOutputStream(); //7.将FileInputStream流写入到buffer缓冲区 while ((len = in.read(buffer)) > 0) { //8.使用OutputStream将缓冲区的数据输出到客户端浏览器 out.write(buffer,0,len); } in.close(); }
  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/quietwalk/p/8609162.html
Copyright © 2011-2022 走看看