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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© nan935682648 初级黑马   /  2018-5-21 15:07  /  555 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小石姐姐 于 2018-5-23 15:25 编辑

JDBC

##JDBC入门:
环境准备:创建数据库和表
导入masql驱动jar包

##JDBC流程:(主题流程,优化这些过程)
**轴心:Connection对象(连接),贯穿流程**    *conn = DriverManager.getConnection(url,username, password);*

~~~java
1. 加载驱动:`Class.forName("com.mysql.jdbc.Driver");`
2. 获得连接:`Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3","root","123");`
    Connection是接口 上条语句为多态
3. 进行操作
```
    CRUD:以查询所有为例
    statement = conn.createStatement();
    String sql = "select * from user";
    //执行sql语句 获得结果集
    rs = statement.executeQuery(sql);
     while(rs.next()) {
        System.out.print(rs.getInt("id")+" ");
        System.out.print(rs.getString("username")+" ");
        System.out.print(rs.getString("password")+" ");
        System.out.print(rs.getString("nickname")+" ");
        System.out.print(rs.getInt("age"));
        System.out.println();
   
    }   
```
4. 释放资源
```
    try {
        rs.close();
        statement.close();
        conn.close();
    } catch (SQLException e) {
        // TODO 自动生成的 catch 块
        e.printStackTrace();
    }
```
~~~

##JDBC的API详解:
* 重要的两个:
* DriverManager:驱动管理类
  - 注册驱动:一般用`Class.format("com.mysql.jdbc.Driver");
  - 获得连接:  DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3","root","123");
* Connection:与数据库链接对象
    - 一个Connection对象对应同一个事务,下面对象均和Connection对象有关


##JDBCUtils工具类:
**因为传统JDBC的开发,注册驱动,获得连接,释放资源这些代码都是重复编写的。所以可以将重复的代码提取到一个类中来完成。**
(更高级的工具类:注册驱动+获得连接=使用开源连接池,从开源连接池获取连接,先介绍中等:配置文件)
定义一个配置文件:
db.properties
内容:

```properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web_test4?rewriteBatchedStatements=true
username=root
password=abc
```



```java
public class JDBCUtils {
    private static final String driverClassName;
    private static final String url;
    private static final String username;
    private static final String password;
   
    static{
        // 获取属性文件中的内容:
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src/db.properties"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        driverClassName=properties.getProperty("driverClassName");
        url=properties.getProperty("url");
        username=properties.getProperty("username");
        password=properties.getProperty("password");
    }   

    /**
     * 注册驱动的方法(同主体)
     */
    public static void loadDriver(){
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
   
    /**
     * 获得连接的方法
     */
    public static Connection getConnection(){
        Connection conn = null;
        try{
            // 将驱动一并注册:
            loadDriver();
            ****
            // 获得连接  得到的对象不知道是哪个实现类的 所以使用多态,也就是面向接口编程
            conn = DriverManager.getConnection(url,username, password);
            ****   
        }catch(Exception e){
            e.printStackTrace();
        }
        return conn;
    }
   
    /**
     * 释放资源的方法
     */
    public static void release(ResultSet rs,Statement stmt,Connection conn){
        // 资源释放:
        //利用实现类重写的close方法,销毁连接
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
        ...
}
```
#连接池:
为什么要有连接池:主体流程中连接的创建和销毁耗时,用户多容易炸
连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。


##开源连接池:
内部解析配置文件-->进行驱动注册-->获得连接Connection对象-->将多个连接存入集合-->提供获得连接的方法
                                                                            |--->连接为增强·Connection实现类·后的对象

Druid开源连接池:

- 阿里旗下,与Spring框架快速整合
- 引入:Mysql驱动包,Druid 的jar包
- 使用:
  1. 在主体流程中直接修改
  * 手动设置参数(了解):

     ```java
         //使用连接池:
         DruidDataSource dataSource = new DruidDataSource();
     
         // 手动设置数据库连接的参数:
         dataSource.setDriverClassName("com.mysql.jdbc.Driver");
         dataSource.setUrl("jdbc:mysql:///web_test4");
         dataSource.setUsername("root");
         dataSource.setPassword("abc");
     
         // 获得连接:
         conn = dataSource.getConnection();
     
     ```

     

  * 配置方式设置参数:

     ```java
          // 使用连接池:
         DruidDataSource dataSource = new DruidDataSource();
         // 从属性文件中获取:
         Properties properties = new Properties();
         properties.load(new FileInputStream("src/druid.properties"));
         //Druid内部解析配置文件,因此自定义的配置文件Key值要和Druid保持一致
         DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
     
         // 获得连接:
         conn = dataSource.getConnection();
     
     ```

     ​      

  2. 修改工具类(C3P0开源连接池为例):
    连接池对象应该是一个应用只创建一次就可以的,不需要每次使用都创建一个新的连接池。
    ```java
    public class JDBCUtils2 {
            // 创建一个连接池:但是这个连接池只需要创建一次即可。
            private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
            
            /**
             * 获得连接的方法
             * @throws SQLException
             */
            public static Connection getConnection() throws SQLException{
                return dataSource.getConnection();
            }
            
            /**
             * 获得连接池:
             */
            public static DataSource getDataSource(){
                return dataSource;
            }
            
            /**
             * 释放资源的方法
             */
            
            public static void release(ResultSet rs,Statement stmt,Connection conn){
                // 资源释放:
                //开源连接池利用装饰者模式增强了Connection 实现类的close方法,不再销毁,而是归还
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    conn = null;
                }
            }
    }
    ```
  







#事务:
    - 指的是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么全都成功,要么全都失败。

事务特性:四个
事务特性:四个

    - 原子性:事务的不可分割,组成事务的各个逻辑单元不可分割。
    -
    - 一致性:事务执行的前后,数据完整性保持一致。
    -
    - 隔离性:事务执行不应该受到其他事务的干扰。
    -
    - 持久性:事务一旦结束,数据就持久化到数据库中。

一个事务:从开启到commit()或rollback();

事务管理的核心操作步骤(维持四个特性):
Connection:conn
开启事务:
    conn.setAutocommit(false);(关闭自动提交)
    自动提交(每执行一条sql语句就自动提交):关掉
    业务逻辑的操作
提交事务:
    conn.commit();(tyr块最后)
一旦有异常:回滚事务
    conn.rollback();(catch块中)

核心思想:业务逻辑的操作使用同一个Connection对象,不同对象不是同一个事务
XML


#XML
##概述:
    - 可扩展标记语言,很类似HTML
    - 设计宗旨是`传输数据`,而非显示数据
    - 标签没有被预定义,需要`自定定义标签`
    - 被设计为具有自我描述性
    - W3C的推荐标准
**允许用户自定义标签!!**
##作用:
    * 传输和存取数据
    * **软件的配置文件**

##使用(编写XML文档):
    1. 基本语法:
        * 必须有根标签
        * XML必须有关闭标签
        * 区分大小写
        * 属性需要有引号
        * 标签必须正确嵌套.
    2. 文档声明(了解):
        * 文档声明:通常出现在XML的第一行第一列的位置!!!
        * 写法:
            * <?xml 属性名=”属性值” 属性名=”属性值” ...?>
            * version    :必须的. 使用”1.0”
            * encoding    :字符集. 是使用浏览器打开的时候采用的默认的字符集的编码.
            * standalone    :描述XML文档是否需要依赖其他的文件.
    3. 注释:<!--XML的注释-->
    4. 元素(标签)的命名规范:
        * 可以包含字母,数字及其他字符
        * 不能以数字或标点符号开始
        * 不能以字符"XML(或者xml ,Xml)"开始
        * 不能包括空格,冒号
    5. 属性的命名规范:同元素.属性需要使用引号
    6. 特殊字符和CDATA区:
        * 特殊字符
            * <  <  小于
            * >  >  大于
            * &  &  和号
            * ' '  单引号
            * " "  引号
   
        * XML的CDATA区:(CDATA:Character Data)
        * 内容都会被当成字符串,不会识别
        * <![CDATA[  内容  ]]>

##XML的解析:
- XML的解析:从XML文档中获得想要的数据(通过代码完成的.)
    **XML的解析的方式(两种解析):**
        * DOM解析:
            * DOM:Document Object Model.
            * Node为所有节点的父类,其他节点对象:Element, Attribute ,Text。通过Document文档对象调用
        * SAX解析:Simple Api for XML.
        * DOM和SAX的区别:
            * DOM:一次性将文档加载到内存,形成树形结构进行解析
                - 缺点:如果文档特别大,容易导致内存的溢出
                - 优点:对XML进行增删改的操作
            * SAX:事件驱动的方式,一行一行进行解析
                - 优点:如果文档特别大,不会导致内存的溢出
                - 缺点:不能对XML进行增删改的操作
- 针对这两种解析的方式,不同的公司提供了不同的API的实现(几种实现方式).
        * JAXP        :SUN公司提供的一套XML的解析的API.
        * JDOM        :开源组织提供了一套XML的解析的API-jdom.
        * DOM4J        :开源组织提供了一套XML的解析的API-dom4j.**
        * pull        :主要应用在Android手机端解析XML.

- DOM4J的入门案例步骤:
        * 【步骤一】导入jar包.dom4j-1.6.1.jar
        * 【步骤二】创建解析器:SAXReader reader = new SAXReader();
        * 【步骤三】解析文档获得代表文档的Document对象.Document document = reader.read("./src/demo01.xml");(将两种解析方式都用了)
        * 【步骤四】获得根节点.
        * 【步骤五】从跟节点下查找其他的节点. element()或elements();
        * 利用DOM4J解析,所以在代码中导入的节点类为DOM4J中的类
        * 缺陷:只能一层一层向下查找

- XPath:一种语法结构(字符串),支持XPath的API才可以使用
        * dom4j支持XPath的jar包.
            * jaxen-1.1-beta-6.jar
        * dom4j的XPath支持的API:
            * 只能获得Node对象,需要时可以强转
            * List document.selectNodes(String xPath);
            * Node document.selectSingleNode(String xPath);
        * XPath的语法:查看参考文档1-6

    ```
    @Test
    public void demo02() throws DocumentException {
        //获得解析器
        SAXReader reader = new SAXReader();
        //解析XML文档
        Document document = reader.read("./src/demo01.xml");
   
        1.
        //利用XPath获得
        List<Node> nodes = document.selectNodes("//person");
        //遍历
        for (Node node : nodes) {
            System.out.println(node.getName());
        }
   
        2.
        //利用XPath获得
        List<Node> nodes = document.selectNodes("//name");
        //遍历
        for (Node node : nodes) {
            System.out.println(node.getText());
        }
        3.
        //利用XPath获得
        List<Node> nodes = document.selectNodes("//person");
        //遍历
        for (Node node : nodes) {
            //由于attributeValue()方法,必须向下强转
            Element ele = (Element) node;
            System.out.println(ele.attributeValue("id"));
        }
    }
    ```
##XML的约束:
    * 什么是XML的约束    :就是用来约束XML的文档中可以出现哪些标签,不能出现哪些标签,标签中是否有顺序,出现的次数.
    * XML的约束    :用来规范XML的写法.
    ***** XML的约束的种类及区别?
         * DTD 和 Schema    :
             * 区别:
                 1.DTD语法是自成一体的.Schema语法就是XML的语法.
                 2.Schema的语法就是XML的语法所以更容易被解析器所解析.
                 3.Schema支持名称空间.
                 4.Schema有比DTD更加强大的语义和语法的约束.
Tomcat和servlet

#软件架构:
**请求与响应模型!!!**

需求:有一个web项目,需要通过tomcat服务器被其他人访问到.

浏览器<--->服务器:程序运行在浏览器和服务器上。浏览器向服务器发送请求,服务器返回响应给浏览器
【软件的架构】

* C/S架构的软件:
        * Client / Server 客户端和服务器端的软件. 都是需要在PC端安装的软件. 比如 QQ,迅雷,暴风...
        * 优点:效果炫,一部分代码写到客户端(速度快).
        * 缺点:服务器端更新,客户端都需要更新.

* B/S架构的软件:
        * Browser / Server 浏览器端和服务器端的软件. 不需要安装到PC端,只需要有一个浏览器即可. 比如 京东,网银,WEBQQ,WEB迅雷...
        * 优点:服务器端更新,客户端浏览器不需要进行更新.
        * 缺点:效果不炫,所有的代码运行都在服务器端,导致服务器压力过大.
            * 效果:使用HTML5,CSS3可以做出很炫效果.
            * 服务器端压力:搭建服务器的集群.而且还有AJAX技术.


【WEB的资源】
静态资源:* HTML,CSS,JS,图片...

动态资源:
    * PHP            :
    * ASP            :
    * Servlet/JSP    :
【服务器】
    - 硬件:其实就是一台配置很高的电脑.
    - 软件:必须在一台电脑上安装服务器软件(中间件).这台电脑称为是WEB服务器.
【常见WEB服务器】
    - Apache        :发布PHP的.LAMP:Linux Apache MySQL PHP.
    - IIS            :发布ASP的.
    - WebSphere        :IBM公司研发,收费的大型服务器软件,支持EE的所有的开发规范.
    - WebLogic        :BEA公司研发,收发的大型服务器软件,支持EE的所有的开发规范.
    - Tomcat            :Apache组织研发,免费的小型的服务器软件,支持Servlet/JSP的开发规范.
    - JBoss            :


【WEB动态资源目录结构】
```
website
    |-----静态资源
    |-----WEB-INF(动态资源都放在这个目录下)
                |-----web.xml    :必须的(用来Servlet的配置,来运行Java程序)
                |-----classes    :可选的(编译后的class文件)
                |-----lib        :可选的
​````
#Tomcat

【目录结构】:
    * bin        :tomcat的执行的文件.
    * conf        :tomcat的配置文件.
    * lib        :tomcat运行的需要的jar包.
    * logs        :tomcat的运行的日志文件.
    * temp        :tomcat产生临时文件存放的路径.
    * webapps    :tomcat发布的web项目的路径.(项目在此路径下)
    * work        :tomcat运行JSP的时候,JSP翻译成Servlet的代码存放的路径.
【发布web项目到Tomcat(服务器)中的方式】:
    * 1.直接将工程copy到tomcat/webapps下.(了解)
    * 2.配置tomcat虚拟路径:
        * 在tomcat/conf/server.xml文件中进行配置:
        * 在<Host>标签下配置:
            * <Context path="/itheima" docBase="C:/website"/>

    * 3.配置tomcat虚拟路径(推荐):
        * 在tomcat/conf/Catalina/localhost/xxx.xml
        * 配置<Context docBase="C:/website"/>
        * xxx作为虚拟路径的名称.(访问时输入此路径)
访问服务器下web项目的流程:
1. 开始:打开服务
2. 方式:`http://ip:port/webProjectName/XXX.html`
【项目运行环境】:在服务器下运行
##开发工具:Eclipse
流程:
        1. 建立web项目
        2. 在WebContent下编写静态资源,有动态资源必须有/WebContent/META-INF
        3. 导出XXX.war包到Tomcat下的/webapps中(或者在Servers右键添加)
        4. 开启服务
        5. 在浏览器端请求服务器

#HTTP协议:
浏览器端向服务器发送请求,服务器将响应返回给浏览器端
【HTTP的协议的概述】
    * 协议:什么是协议:规定双方需要遵守的规则.
    * HTTP协议:什么是HTTP协议:用来规定浏览器与服务器之前需要遵守的规则.
   
    1. HTTP协议的作用:规范浏览器和服务器之间的数据传递.
    2. HTTP协议的特点:
        * 基于请求和响应的模型.
            * 必须先有请求后有响应.
            * 请求和响应必须成对出现.
        * 默认的端口号是80(如果服务器端口号是80也就不用写了).
    3. HTTP协议的版本:
        * 1.0    :每次响应后即刻关闭了连接.
        * 1.1    :现在使用.不是每次响应后挂断,等待长时间以后没有请求会挂断.
【HTTP协议的演示】
    抓包分析:GET方式:
    * 请求部分:(浏览器端请求服务器)
        //请求行:请求方式 ,请求路径,请求协议
        GET /day09/demo1-http/demo2.html?name=aaa&age=23 HTTP/1.1  
        //请求头
        Accept: text/html, application/xhtml+xml, */*
        X-HttpWatch-RID: 59176-10011
        Referer: http://localhost:8080/day09/demo1-http/demo1.html
        Accept-Language: zh-CN
        User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
        Accept-Encoding: gzip, deflate
        Host: localhost:8080
        DNT: 1
        Connection: Keep-Alive
        //请求体:GET没有请求体,因此是空行

    抓包分析:POST方式:
        POST /day09/demo1-http/demo2.html HTTP/1.1
        Accept: text/html, application/xhtml+xml, */*
        X-HttpWatch-RID: 59176-10031
        Referer: http://localhost:8080/day09/demo1-http/demo1.html
        Accept-Language: zh-CN
        User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
        Content-Type: application/x-www-form-urlencoded
        Accept-Encoding: gzip, deflate
        Host: localhost:8080
        Content-Length: 15
        DNT: 1
        Connection: Keep-Alive
        Cache-Control: no-cache

        //请求体
        name=bbb&age=38
【两种请求方式包含】:目前只有表单提交使用post方式。
【HTTP协议的详解】
请求部分
    * 请求行
        * 提交方式:
            * 提交方式有很多,常用的GET和POST:
            * GET和POST的区别:
                * GET的提交的参数会显示到地址栏上,而POST不显示.
                * GET往往是有大小限制的,而POST没有大小的限制.
                * GET没有请求体,而POST有请求体.
        * 提交路径:
        * 协议版本:
    * 请求头
        * 都是键值对的形式显示的.一般一个key对应一个value,也有个别的是一个key对应多个value.
        * User-Agent                :代表浏览器的类型. --- 文件下载:下载中文文件:IE使用URLEncodor进行编码,而Firefox使用Base64编码.
        * Referer                :代表的是网页的来源. --- 防盗链.
        * If-Modified-Since        :通常与响应中的头Last-Modified一起使用查找本地缓存.
    * 请求体
        * 就是POST提交方式的提交的参数.
响应部分
    * 响应行:
        * 协议版本
        * 状态码        :
            * 200    :成功
            * 302    :重定向
            * 304    :查找本地缓存
            * 404    :资源不存在
            * 500    :服务器内部错误
        * 状态码描述
    * 响应头:键值对,一般一个key对应一个value,也有一个key对应多个value.
        * Last-Modified            :与请求中的If-Modified-Since一起使用查找本地缓存.
        * Content-Dispostion    :文件下载的使用使用的一个头信息.
        * Location                :重定向的跳转的路径.
        * Refresh                :定时刷新/定时跳转.
    * 响应体:显示浏览器的页面的内容.
#【Servlet的概述】
什么是Servlet:
    * 就是一个运行在WEB服务器上的小的Java程序,用来接收和响应从客户端发送过来的请求,通常使用HTTP协议.
    * Servlet就是SUN公司提供的一个动态网页开发技术.
Servlet的作用:
    * 用来处理从客户端浏览器发送的请求,并且可以对请求作出响应
使用Servlet:
    * 编写一个类实现Servlet接口.
    * 将编写的这个类配置到服务器中.
Servlet的入门:
* 编写类:
```
public class ServletDemo1 implements Servlet{

    @Override
    /**
     * 为用户处理请求和响应的方法.
     */
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        //解决中文乱码看15天笔记
        req.setCharacterEncoding("utf8");
        String name = req.getParameter("name");
        String password = req.getParameter("password");
        String sex = req.getParameter("sex");
        String[] city = req.getParameterValues("city");
        String info = req.getParameter("info");
        
        System.out.println(name);
        System.out.println(password);
        System.out.println(sex);
        System.out.println(info);
        for (String string : city) {
            System.out.print(string +" ");
        }
    }
...
}
```
* 配置:


```
* 在WEB-INF中的web.xml中配置
  <!-- 配置Servlet -->
  <servlet>
      <!-- Servlet的名称 -->
      <servlet-name>test1</servlet-name>
      <!-- SErvlet的全路径 -->
      <servlet-class>com.itheima.a_servlet.ServletDemo1</servlet-class>
  </servlet>

  <!-- Servlet的映射 -->
  <servlet-mapping>
      <!-- Servlet的名称 -->
      <servlet-name>test1</servlet-name>
      <!-- Servlet的访问路径 -->
      <url-pattern>/ServletDemo1</url-pattern>
  </servlet-mapping>

* 访问:
  http://localhost:8080/day09/ServletDemo1
【使用ServletRequest接收参数】

```java
* String getParameter(String name);        ---用于接收一个名称对应一个值的数据.

* String[] getParameterValues(String name);---用于接收一个名称对应多个值的数据.

* Map getParameterMap();                   ---用于接收表单中的所有的数据,Map的key是表单提交的参数名称,Map的value是提交参数的值.

* Enumeration getParameterNames()           ---用于获取表单中提交的所有的参数的名称

```

【Servlet的访问流程 】

```
结合生命周期理解:服务器给每个servlet创建一个对象,用户访问时对象调用service方法--->service方法--->doXXX方法
```

【Servlet的实现的关系】

```java
Servlet         :接口

   |

GenericServlet  :通用的Servlet

   |

HttpServlet     :HttpServlet

* 编写一个类继承HttpServlet,重写doGet和doPost方法.

* 配置
```

#### 【Servlet的生命周期】

```
Ø  生命周期:就是一个对象从创建到销毁的过程.

Ø  Servlet生命周期: 
    1,初始化阶段  调用init()方法
    2,响应客户请求阶段  调用service()方法
    3,终止阶段  调用destroy()方法


* 何时创建:用户第一次访问Servlet创建Servlet的实例

* 何时销毁:当项目从服务器中移除的时候,或者关闭服务器的时候.

     用户第一次访问Servlet的时候,服务器会创建一个Servlet的实例,那么Servlet中init方法就会执行.任何一次请求服务器都会创建一个新的*线程*访问Servlet中的service的方法.在service方法内部根据请求的方式的不同调用doXXX的方法.(get请求调用doGet,post请求调用doPost).当Servlet中服务器中移除掉,或者关闭服务器,Servlet的实例就会被销毁,那么destroy方法就会执行.
     Servlet是单例,每个类的Servlet对象只有一个
     但是一个工程中不同Servlet类的对象不同,ServletContext域对象只有一个
```

```
思想:由于第一次访问servlet耗时,所以将对象创建放在服务器启动时 。看截图
```

【Servlet的相关的配置 】

```
【启动时创建Servlet】:配置完成后所有的servlet对象均适用
Servlet默认是在第一次访问的时候创建的.现在让Servlet在服务器启动的时候创建好.进行对Servlet的配置:
在web.xml中在<servlet></servlet>标签中配置:
* <load-on-startup>2</load-on-startup>  --- 传入正整数,整数越小,被创建的优先级就越高.



【url-pattern的配置】
url-pattern配置方式共有三种:
1.完全路径匹配    :以 / 开始                例如:    /ServletDemo4 , /aaa/ServletDemo5 , /aaa/bbb/ServletDemo6
2.目录匹配        :以 / 开始 需要以 * 结束.    例如: /* ,/aaa/* ,/aaa/bbb/*
3.扩展名匹配        :不能以 / 开始 以 * 开始的. 例如: *.do , *.action
***** 错误的写法    : /*.do
如果访问地址:
http://localhost:8080/day09/ServletDemo4        :第一个
http://localhost:8080/day09/aaa.do                :第二个
***** 完全路径匹配 > 目录匹配 > 扩展名匹配

```

【开发中的路径的编写 】

```
获取web项目中文件前置点
绝对路径:不需要找位置相对关系. 以 / 开始的.
* 绝对路径中分为客户端路径和服务器端路径:
    * 客户端路径一定要加工程名.        /day09/ServletDemo6
    * 服务器端路径不需要加工程名.    /ServletDemo6
```

【ServletContext对象 】

```java
* 用来向ServletContext中存入数据.
void setAttribute(String name,Object object)
* 用来从ServletContext中获取数据.
Object getAttribute(String name)
* 用来从ServletContext中移除数据.
void removeAttribute(String name)
```

【ServletConfig:了解.获得Servlet的配置信息 】

```java
* String getServletName();        ---获得Servlet在web.xml中配置的name的值.
* String getInitParameter(String name);    ---获得Servlet的初始化参数的.
```



```
【静态资源与动态资源】:
静态资源可以为动态效果提供入口,也可以直接访问动态资源
表单提交:在静态的登录、注册页面,通过提交表单到:`http://localhost:8080/day09/ServletDemo1`(是一种请求) 在Java程序中得到请求,获得表单信息
```





# 工程中文件路径


###须知


发布在服务器中的web工程在获取文件时和开发工具中的路径不同,详情看导写


网站被人使用,所以需要进行线上测试


###读取WEB工程下的文件


【使用ServletContext对象读取WEB项目下的文件】:


```
有servlet环境下使用,解释看导写
```


```java
//InputStream getResourceAsStream(String path); --- 根据提供路径读取文件返回一个文件的输入流.
ServletContext context = this.getServletContext();


InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");


```


```java
// 获得ServletContext:
ServletContext context = this.getServletContext();
// 获得该文件的磁盘绝对路径.
String realPath = context.getRealPath("/WEB-INF/classes/db.properties");
System.out.println(realPath);
InputStream is = new FileInputStream(realPath);
```


【类加载器读取文件 】:


```
无servlet环境下,其他类中获取文件。解释看导写
```


```java
InputStream is = ReadFileUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(is);
```


#### ServletContext的功能


【功能一:读取全局初始化参数】


```java
//配置全局初始化参数:
  <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>
//读取
String username = this.getServletContext().getInitParameter("username");
String password = this.getServletContext().getInitParameter("password");


```


【功能二:获得文件的MIME的类型】


```java
//供文件下载使用
String type = this.getServletContext().getMimeType("1.html");
```


【功能三:作为域对象存取数据】


```
范围:整个web项目.而且全局的对象.
创建:服务器启动的时候,服务器为每个web项目创建一个单独的ServletContext对象.
销毁:服务器关闭的时候销毁ServletContext.
```


【功能四:读取web项目下的文件】:


### 文件的下载


```
需求:在登录成功后,页面跳转到文件下载的列表的页面,点击列表中的某些链接,下载文件.
```


【文件下载的方式】


```
一种:超链接下载.直接将文件的路径写到超链接的href中.---前提:文件类型,浏览器不支持.
二种:手动编写代码的方式完成文件的下载.
* 设置两个头和一个流:
    * Content-Type                        :文件的MIME的类型.
    * Content-Disposition        :以下载的形式打开文件.
    * InputStream                        :文件的输入流.
```


【环境的准备】


```html
get请求,将参数放入地址栏,参数在地址栏会进行编码 eg:美女--->#EDJK%FEJKL需要解决中文乱码
<a href="/weblogin/download?filename=123.jpg">123.jpg</a><br>
<a href="/weblogin/download?filename=美女.txt">美女.txt</a><br>
<a href="/weblogin/download?filename=妮娜.jpg">妮娜.jpg</a><br>
<a href="/weblogin/download?filename=bal.zip">bal.zip</a><br>
```


```java
//servlet对象获得请求后提取filename(提供的文件名),利用文件名去获取文件(servlet环境下两种方式)
String filename = new String ( request.getParameter("filename").getBytes("ISO-8859-1"),"UTF-8");
//设置响应的两个头(存在中文时需要将弹出框名字设置语句放在获取输入流后面)--->获取工程中的文件(输入流)--->获取响应的输出流--->输出到浏览器
// 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头,输出到下载弹出框中文乱码问题需要在此语句上面解决
/*Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。 */
response.setHeader("Content-Disposition", "attachment;filename="+filename);
```


### 中文乱码


### 【网络IO的编码问题】


#### response输出相应内容乱码:


##### 向页面响应的方法


* getOutputStream();
* getWriter();


```
* 这两个方法是互斥的.
    * 做出响应的时候只能使用其中的一种流响应.
```


#####输出中文乱码的处理


```java
【向页面输出】
* 字节流:
        设置浏览器默认打开的编码:
                * 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");
【向浏览器弹出框输出】
// 根据浏览器(火狐浏览器为例)的类型处理中文文件的乱码问题:
                //获得浏览器的版本信息
                String agent = request.getHeader("User-Agent");
                if(agent.contains("Firefox")){
                        filename = base64EncodeFileName(filename);
                }else{
                        filename = URLEncoder.encode(filename,"UTF-8");
                }
// 设置Content-Disposition头,输出到下载弹出框中文乱码问题需要在此语句上面解决
/*Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。 */
response.setHeader("Content-Disposition", "attachment;filename="+filename);
```


##### 输入中文乱码的处理


```java
【现在无论是GET还是POST提交中文的时候,都会出现乱码的问题】
解决:
POST的解决方案:
* POST的参数在请求体中,直接到达后台的Servlet.数据封装到Servlet中的request中.request也有一个缓冲区.request的缓冲区也是ISO-8859-1编码.因此只要设置缓冲区的编码,让它可以识别中文(须和html页面编码一致)
* 设置request的缓冲区的编码:
    * request.setCharacterEncoding(“UTF-8”);  --- 一定要在接收参数之前设置编码就OK.
GET的解决方案:
* 1.修改tomcat的字符集的编码.(不推荐)
* 2.使用URLEncoder和URLDecoder进行编码和解码的操作.
* 3.使用String的构造方法:
GET方法向后台传参时参数先编码到地址栏,然后再编码成*ISO-8859-1*,因此需要对称解码
String filename = new String ( request.getParameter("filename").getBytes("ISO-8859-1"),"UTF-8");
```






0 个回复

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