精华内容
下载资源
问答
  • Tomcat新特性:支持Servlet3.0注解定义,无需配置web.xml 前言 tomcat从7.0版本开始就支持Servlet3.0,在Eclipse中不再需要web.xml配置servlet,而通过注解的方式找寻servlet。 电脑环境: Windows10教育版 ...

    Tomcat新特性:支持Servlet3.0注解定义,无需配置web.xml

    前言

    tomcat从7.0版本开始就支持Servlet3.0,在Eclipse中不再需要web.xml配置servlet,而通过注解的方式找寻servlet。

    电脑环境:

    Windows10教育版 64位 (OS内部版本:16299.125)
    jdk版本:jdk1.8_111
    Eclipse版本:eclipse-jee-oxygen-2-win32-x86_64
    tomcat版本:tomcat8.0
    MySQL的JDBC驱动程序版本:mysql-connector-java-5.1.46.zip

    步骤

    1、首先打开Eclipse软件,打开后在工具栏依次点击【File】——>【New】——>【Dynamic Web Project】,这个就代表新建的项目是WEB项目。
    2、填写项目的基本信息,包括项目名、项目运行时服务器版本。可以选择tomcat或者其他都可以,看项目需要。在这里我们输入一个【TestTomcat8】来测试项目的建立,输入完毕后我们点击【Next】按钮。
    这里写图片描述
    3、这个窗口显示的WEB项目中需要编译的JAVA文件的目录,默认是SRC目录,这个我们不需要改,直接点击【Next】。
    这里写图片描述
    4、接着弹出窗口,显示的是我们的WEB项目,WEB文件相关的目录,就是html或者jsp还有js那些web相关的文件存放的目录,默认是【WebContent】,你也可以修改成你想要的文件名,不用勾选创建web.xml复选框。然后点击finish。
    这里写图片描述
    5、右键点击项目,然后New——>Servlet。
    这里写图片描述
    6、在对话框中输入包名cn.nicktcl.test.hello和类名HelloWorld2,点击finish。
    这里写图片描述
    7、将以下代码粘贴到文件HelloWorld2.java如下位置。
    这里写图片描述

                PrintWriter out = response.getWriter();  
                out.write("<html>\r\n");  
                out.write("<head>\r\n");  
                // 设定解码方式  
                out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");  
                out.write("</head>\r\n");  
                out.write("\r\n");  
                out.write("<body>\r\n");  
                out.write("<H1>\r\n");  
                out.write("helloworld2");  
                out.write("\r\n");  
                out.write("</H1>\r\n");  
                out.write("</body>\r\n");  
                out.write("</html>");  
        }

    8、点击运行按扭旁边的小箭头——>Run As——>Run on Sever。
    这里写图片描述
    9、点击finish。
    这里写图片描述
    10、控制如出现如下界面则说明tomcat已经在后台运行。
    这里写图片描述
    11、我们打开自己的浏览器,在地址栏输入以下路径验证是否可以访问到刚写的页面:http://localhost:8080/TestTomcat8/HelloWorld2,其中Hello是项目的名称,HelloWorld是类名称。可看到正常输出HelloWorld2。
    这里写图片描述

    参考资料

    1、Tomcat7.0新特性:支持Servlet3.0注解定义,无需配置web.xml
    2、Servlet2.5和 3.0区别(Servlet 3.0 新特性详解)

    展开全文
  • 几天要做的 认识 的spring的是 : 数据源 的 ...dbcp :Tomcat 内置的 c3p0 的使用 : 关闭数据库 归还的 到数据库连接池POOLED 里 c3p0,Druid 的 spring 集成 的使用 的 : 的 基于注解的 IOC...

    要做的 认识 的spring的是 :

    ====== 进行 xml 或 全注解 的通用 的 实验 =========

    小需求 : 实现账户的 CRUD 操作 ========

    技术要求

    使用 全注解 开发

    使用 spring 的 IoC 实现对象的管理

    使用 DBAssit 作为持久层解决方案 使用 c3p0 数据源

    回顾 在前一篇里 我们已经对于spring 的 的基本面的 认识 :

    spring 框架所拥有的生态 : 有 7个 :ioc aop 事务 测试 集成 模板 源码学习
    提供了 后端3层 的 解决方案 :

    1: 表现层(控制层) springMVC
    2: 持久层 SpringDate /或者还有封装jdbc 操作的模板
    3: 与spring 的业务层

    最新的版本迭代 是Spring5
    spring 的2个core :IOC 与 AOP
    一个重要作用 : 整合 其他的开源框架

    他的核心 ioc 所实现的原理 :

    依赖反转 将创建 对象  托付  给spring进行管理 交给spring 来做,----------
     让 spring  给代理了  --------- 而 spring是的ioc 的实现方式 也有 他的 代理方式-------- 
     动态代理  -------动态代理 2种 的实现:java jdk 基于接口 与  cglib  基于 父类 与 子实现类 --------- 
     都是要 基于反射  ---------- 而反射:需要java编写程序的代码文件------- 
     3个获取  ------加载类加载器  。。。。。
    

    注解+ xml 配置 : Spring 开发的时候

    第三方jar 包 用的是xml 实际中 纯 xml 配置 已经很少在用

    基于xml 的注解 : 作用 于 crud 的增删改查 :

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 加载数据库 配置文件 -->
    <context:property-placeholder location="classpath:jdbcConfig.properties"></context:property-placeholder>
        <!--   包扫描  -->
        <context:component-scan base-package="com.fhw"></context:component-scan>
        <!--  配置 sercice -->
    <bean id="accountServiceI" class="com.fhw.service.impl.AccountServiceImpl">
        <!-- 注入dao -->
     <property name="dao" ref="accountDao"></property>
    </bean>
        <!--  配置 dao -->
        <bean id="accountDao" class="com.fhw.dao.impl.AccountImpl">
            <!--  注入 QueryRunner -->
            <property name="query" ref="queryRunner"></property>
        </bean>
        <!--  配置 QueryRunner -->
        <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
            <constructor-arg name="ds" ref="dataSource"></constructor-arg>
        </bean>
    
        <!--<bean id="" class=""></bean>-->
        <!--配置数据源的 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver}"></property>
            <property name="jdbcUrl" value="${jdbc.url}"></property>
            <property name="user" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
    
            </beans>
    
    

    在这里插入图片描述

    3 同样可以 完成 CRUD 的操作 :

    .1 需求和技术要求
    1.1.1 需求
    实现账户的 CRUD 操作
    1.1.2 技术要求
    使用 spring 的 IoC 实现对象的管理 使用 DBAssit 作为持久层解决方案 使用 c3p0 数据源

    测试

    import com.fhw.pojo.Account;
    import com.fhw.service.IAccountService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.List;
    
    public class AccountTest {
        @Test
        public void testFindAll(){
    //     获取 容器
            ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    //
            IAccountService accountService = ac.getBean("accountServiceI", IAccountService.class);
            List<Account> allAccount = accountService.findAllAccount();
            for (Account account : allAccount) {
                System.out.println(account);
            }
        }
    

    在注入的 时候 写 的业务类 常用 是 set 的

    public class AccountImpl implements IAccountDao {
        private QueryRunner query;//用apache 的工具类 来进行
    
        public void setQuery(QueryRunner query) {
            this.query = query;
        }
    
    
    public class AccountServiceImpl implements IAccountService {
        private IAccountDao dao =new AccountImpl();
    
        public void setDao(IAccountDao dao) {
            this.dao = dao;
        }
    
    
    测试图 =======

    在这里插入图片描述

    html 做表现 的 xml 做配置

    后面的注解开发就会 : 常用 @Autowired 就不用set 了

    纯注解的开发的 在springBoot 里比较常用 或 自定义 的类

    数据源 的
    都要实现的额接口 都是 实现 DataSource 接口 都是 使用getConnection 对象
    c3p0 dirud 在这里插入图片描述
    dbcp :Tomcat 内置的
    在这里插入图片描述
    c3p0 的使用 :

    关闭数据库 归还的 到数据库连接池POOLED 里

    c3p0,Druid 的 spring 集成 的使用 的 :

    基于注解的 IOC 配置 :

    都是减低程序之间的耦合 : 使用的是依赖反转的思想 :
    入门的操作 :
    3个注解 :
    @Compont :只加这个注解 : Bean 的id 默认 是该类名称的 首字母小写
    ---- 使用 value 属性 来指定Bean的id 名称 就是你的自定义
    使用位置 : 实现类的作用 : 让spring 反射 创建该类的实
    @Autowired +@Qualifier (id)
    在@ @Compont 是如何 然Spring 的识别的 就要
    要告知 spring 在那些包 及子包 下 在这里插入图片描述
    配置组件扫描 :

    IOC :纯注解 ‘: 不用xml 了 : 用 注解来实现 :
    一旦使用注解之后 就 不用 再 需要该 类 的 set方法 了

    在这里插入图片描述

    纯注解的开发的 在springBoot 里比较常用 :

    所用的还是 ; CURD 的 增删改查 的

    在注解 应用的 时候 先来认识 一下 : : 这些 各种的注解 是 如何 代替 xml 的 :

    实现 定义bean 方面的 注解 :

    @Component 相当于在 xml 中配置一个 bean。

    value:指定 bean 的 id。不指定 value 属性,默认 bean 的 id 是当前类的类名 的首字母小写。

    下来的是3层的 “ bean” 注解
    @Controller ===== 控制层 的
    @Service ===== 业务层 的
    @Repository ===== 持久层 的
    以上的注解 一加 之后 就会 出现小豆豆 Bean 的图形了

    比如到最后 纯注解的 的这张图 :
    在这里插入图片描述

    使用3层的时候 注解的 时候 : 需要一的包扫面 ,这时候 还需要 xml 得来搭配的 : 在接下来的经理种将会 组不到 摘除 xml 相关的

    在这里插入图片描述

    问题 那些坑 bug 有图 有真相;,

    在这里插入图片描述

    相同且 无法分辩:

    在这里插入图片描述

    在这里插入代码片
    
    接着会用到的是 :
    会用到的 注入的 的 注解  @Autowired 自动注入 ==
    @Qualifier 这个 用的少 :
    单一的匹配,不安全,应该是类型+id名字 双重进行匹配
    <!-- DI注解解析器 -->
    
    <context:annotation-config/>
    
    Autowired的特点:
    
    首先按照类型去找,然后再按字段的名字(xml中的id属性)去找,两者都找不到就报错。匹配上就会注入进去。
    
    属性名字相同,xml中的id属性也相同: Bean name 'employ1' is already used in this <beans> element
    
    属性名字与xml中的id属性不相同,
    
    expected single matching bean but found 2: employ1,employ2
    
     
    
    单一的匹配,不安全,应该是类型+id名字 双重进行匹配
    
    @Autowired:如果使用单一个注解的话  一定要使用 DI注解解析器。
    
    @Qualifier("employ1")//用的很少  除非同一种类型的bean有多种定义的时候才会用的到--通过id去取
    
     
    
    @Autowired//根据类型找
    
    @Qualifier(value="mysqlDataSourceBean")//在根据名字找
    
     
    
    //相同类型的bean有多个  但是bean的id不同  
    
    <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource"/>
    
    <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource"/>
    --------------------- 
    原文:https://blog.csdn.net/m0_37871296/article/details/88778932 
    
    

    余下的 这些注解 :

    @Resource

    作用: 直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。 属性: name:指定 bean 的 id。

    @Value

    作用: 注入基本数据类型和 String 类型数据的 属性: value:用于指定值
    2.3.3 用于改变作用范围的:
    相当于:

    @Scope

    作用: 指定 bean 的作用范围。 属性: value:指定范围的值。 取值:singleton prototype request session globalsession

    和生命周期相关的:(了解)

    相当于:

    @PostConstruct

    作用: 用于指定初始化方法。

    @PreDestroy
    
    /*
    *  回顾一下  : xml 配置的注意
    *  <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
     *        scope=""  init-method="" destroy-method="">
     *      <property name=""  value="" | ref=""></property>
     *  </bean>
     *   ***** 注解的annotation的 里 要做是
     *      注解与xml  异曲同工  的   还是 作用与 bean 的
     *      这些  注解   bean 的 注入 spring 日容器 里
     *       @Component 只一个 总的注解
     *       -- 分别有 对应3层的注解 : 注入的 3 层区域的注解
     *          @Controller    控制层
     *          @service   : 业务层
     *          @Repository : 持久层
     *     具体注入的
      *     ============   bean类 引用数据的*** 注入***  注解  ===================
     *     @Autowired  :  自动注入  相当于 xml   的  property
     *       确定  id 的 唯一 就会注入
     *     但有多个类型 的时候
     *     ****** 位置上 : 变量 方法 上
     *         ***** 细节 : 除了 set 方法 还有替他的
     *     @Qualifier : 以名称注入 配合 Autowired 的 使用
     *       @Qualifier + @Autowired   来使用 的
     *    在入参的时候  可以使用 :
     *    @Resource  直接的注入 :
     *      ===============  @Value 基本数据  与   字符串的 *** 注入*** 使用的注解  ===============
     *   @Value  基本数据  与   字符串的注入 使用的是  value
     *     ===============   @Scope 改变作用域的*** 注入*** 使用的注解  ===============
     *        取值 : singleton   与  prototype
     *        ===============   @ 生命周期*** 注入*** 使用的注解  ===============
     *        PostConstruct : 初始化
     *        preDestroy  销毁
     *
     *
     *
    *   */
      @Value("user")
     private String  username;
    
        //   private IAccountDao accountDao=new AccountDaoImpl();
    @Autowired()//会 自动的找到 子实现类 进行注解  :
    //@Resource(name = "Autowired_qualifier_noSpringNojdk9")//jdk9 已经不再支持来了
       private IAccountDao accountDao;
    @PostConstruct
        public void init() {
            System.out.println("accountService 初始化执行了 ......"); }
    @PreDestroy
        public void destrory() {
            System.out.println("accountService 销毁 前的  方法执行了 ......"); }
        public void saveAccount() {
            System.out.println("accountService执行了 ....");
            System.out.println("\"Value注解 注入的是是 前提是要有<context:property-placeholder location=\\\"classpath:jdbcConfig.properties"+username);
    }
    
    

    我们一案例来进行一个 curd 增删改查 的 账户操作 为 原型 ====

    ====== 进行 全注解 的通用 的 实验 =========

    小需求 : 实现账户的 CRUD 操作 ========

    技术要求

    使用 全注解 开发

    使用 spring 的 IoC 实现对象的管理

    使用 DBAssit 作为持久层解决方案 使用 c3p0 数据源

    pom
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.fhw</groupId>
        <artifactId>springboot_all_annotation_01</artifactId>
        <version>1.0-SNAPSHOT</version>
            <dependencies>
                <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                    <version>5.0.2.RELEASE</version>
                </dependency>
    
                <dependency>
                    <groupId>commons-dbutils</groupId>
                    <artifactId>commons-dbutils</artifactId>
                    <version>1.4</version>
                </dependency>
    
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.6</version>
                </dependency>
    
                <dependency>
                    <groupId>c3p0</groupId>
                    <artifactId>c3p0</artifactId>
                    <version>0.9.1.2</version>
                </dependency>
    
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.10</version>
                </dependency>
            </dependencies>
    
        
    </project>
    
    账户类 : pojo【 实体类 】 实现序列化接口 implements Serializable
    package com.fhw.pojo;
    
    import java.io.Serializable;
    
    public class Account implements Serializable{
    private Integer id;
    private String name;
    private Float money;
    
    get ..... set ....
    }
    
    
    service 层 接口与 实现类 :
    package com.fhw.service;
    
    import com.fhw.pojo.Account;
    
    import java.util.List;
    
    /**
     * 账户业务层的接口
     */
    public interface IAccountService {
    
        /**
         * 模拟保存账户
         */
        void saveAccount(Account account);
    
        /**
         * 查询 所有
         * @param
         * @return
         */
        List<Account> findAllAccount();
        /**
         *  根据id  查询
         * @param id
         * @return
         */
        Account findById(Integer id);
    
    
    
        /**
         *  删除
         * @param id
         */
        int deleteAccount (Integer id);
    
        /**
         * 更新
         * @param account
         */
        void updateAccount(Account account);
    }
    
    

    service层 的 实现类 :

    package com.fhw.service.impl;
    
    import com.fhw.dao.IAccountDao;
    import com.fhw.pojo.Account;
    import com.fhw.service.IAccountService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import java.util.List;
    
    /**
     * 账户的业务层实现类
     */
    //@Component("accountServiceComponent")//  @Component 只一个 总的注解
    @Service("accountService")
    //@Scope("prototype")
    public class AccountServiceImpl implements IAccountService {
        @Autowired()
        private IAccountDao dao;
    
        /**
         * 模拟保存账户
         */
        public void saveAccount(Account account ) {
            dao.saveAccount(account);
        }
        /**
         * 查询 所有
         * @param
         * @return
         */
        public List<Account> findAllAccount() {
            return dao.findAllAccount();
        }
        /**
         *  根据id  查询
         * @param id
         * @return
         */
        public Account findById(Integer id) {
            return dao.findById(id);
        }
    
        /**
         *  删除
         * @param id
         */
        public int deleteAccount(Integer id) {
            return dao.deleteAccount(id);
        }
        /**
         * 更新
         * @param account
         */
        public void updateAccount(Account account) {
      dao.updateAccount(account);
        }
    }
    
    

    持久层 的接口与实现类 :

    package com.fhw.dao;
    
    import com.fhw.pojo.Account;
    
    import java.util.List;
    
    /**
     * 账户的持久层接口
     */
    public interface IAccountDao {
    
        /**
         * 模拟保存账户
         */
        void saveAccount(Account account);
    
        /**
         * 查询 所有
         * @param
         * @return
         */
        List<Account> findAllAccount();
        /**
         *  根据id  查询
         * @param id
         * @return
         */
        Account findById(Integer id);
    
    
    
        /**
         *  删除
         * @param id
         */
        int deleteAccount (Integer id);
    
        /**
         * 更新
         * @param account
         */
        void updateAccount(Account account);
    }
    
    

    持久层 的 接口 实现类
    package com.fhw.dao;
    
    import com.fhw.pojo.Account;
    
    import java.util.List;
    
    /**
     * 账户的持久层接口
     */
    public interface IAccountDao {
    
        /**
         * 模拟保存账户
         */
        void saveAccount(Account account);
    
        /**
         * 查询 所有
         * @param
         * @return
         */
        List<Account> findAllAccount();
        /**
         *  根据id  查询
         * @param id
         * @return
         */
        Account findById(Integer id);
    
    
    
        /**
         *  删除
         * @param id
         */
        int deleteAccount (Integer id);
    
        /**
         * 更新
         * @param account
         */
        void updateAccount(Account account);
    }
    
    

    持久层 的 实现类

    持久层 用的是 :

    package com.fhw.dao.impl;
    
    
    import com.fhw.dao.IAccountDao;
    import com.fhw.pojo.Account;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Repository;
    
    import java.sql.SQLException;
    import java.util.List;
    
    /**
     * 账户的持久层实现类
     */
    @Repository("accountDao")
    public class AccountDaoImpl implements IAccountDao {
      @Autowired()
        private QueryRunner query;
    
        /**
         * 模拟保存账户
         */
            public void saveAccount(Account account) {
                try {
                    query.update("insert into account( name money ) values( ?,?)",account.getName(),account.getMoney());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
    
            }
        /**
         * 查询 所有
         * @param
         * @return
         */
            public List<Account> findAllAccount() {
                try {
                    return query.query("select * from account",new BeanListHandler<Account>(Account.class));
                } catch (Exception e) {
                    throw new  RuntimeException(e);
                }
            }
        /**
         *  根据id  查询w
         * @param id
         * @return
         */
            public Account findById(Integer id) {
                try {
                    return query.query("select * from account where id = ? ",new BeanHandler<Account>(Account.class),id);
                } catch (Exception e) {
                    throw new  RuntimeException(e);
                }
            }
        /**
         *  删除
         * @param id
         */
            public int deleteAccount(Integer id) {
                try {
                    return query.update("delete from account where id = ? ",id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        /**
         * 更新
         * @param account
         */
            public void updateAccount(Account account) {
                try {
                    query.update("update account set name = ? ,money = ? where id = ?",account.getName(),account.getMoney(),account.getId());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
    
    }
    
    

    配置类 的 使用

    父类 的 配置类 :

    package com.fhw.config;
    
    import org.springframework.context.annotation.*;
    
    /*
    * 该类的是一个配置类
    *@Configuration : 用于指定是一个配置类
    * @ComponentScan : 用于 指定要扫描 的包 底层还是 数组 的实现
    * @Bean 是 在执行方法后的结果 一Bean的方式 来 注入到IOC 里
    * ------  不指定属性的时候   就是该方法的 名称
    * @import : 作用于其他 的 配置类
     *  */
    //@Configuration("springConfiguration")
    //不写的时候 就要在 AnnotationConfigApplicationContext(SpringConfiguration.class);
    //@Configuration
    @ComponentScan( "com.fhw")
    @Import(DataConfig.class)
    @PropertySource("classpath:com/fhw/jdbcConfig.properties")
    public class SpringConfiguration {
    }
    
    

    子的 配置类 :

    package com.fhw.config;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.apache.commons.dbutils.QueryRunner;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.sql.DataSource;
    import java.beans.PropertyVetoException;
    
    /**
     * spring 配置类 的 连接数据库
      */
    //@Configuration
    public class DataConfig {
        @Value("${jdbc.driver}")
        private String Driver;
        @Value("${jdbc.url}")
        private String JdbcUrl;
        @Value("${jdbc.username}")
        private String User;
        @Value("${jdbc.password}")
        private String Password ;
    
        /**
         * 创建 QueryRunner 对象
         * @param dataSource
         * @return
         *///  javax.sql.DataSource;
        @Bean("runner")//如果该方法有参数  回去容器里找  , 查找 原理  与 Autowired 一样 的
        public QueryRunner createQueryRunner(DataSource dataSource){
            return new QueryRunner( dataSource);
        }
        @Bean("dataSource")
        public  DataSource createDataSource(){
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(Driver);
                ds.setJdbcUrl(JdbcUrl);
                ds.setUser(User);
                ds.setPassword(Password);
                return ds;
            } catch (PropertyVetoException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    
    properties 配置文件 :
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/spring_c3p0_test001
    jdbc.username=root
    jdbc.password=root
    

    测试类

    package com.fhw.test;
    
    import com.fhw.config.SpringConfiguration;
    import com.fhw.pojo.Account;
    import com.fhw.service.IAccountService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import java.util.List;
    
    public class AccountTest {
        @Test
        public void testFindAll(){
      ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
            //
            IAccountService accountService = ac.getBean("accountService", IAccountService.class);
            List<Account> allAccount = accountService.findAllAccount();
            for (Account account : allAccount) {
                System.out.println(account);
            }
        }
        @Test
        public void testSave(){
    //     获取 容器
            ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
    //
            IAccountService accountService = ac.getBean("accountService", IAccountService.class);
            Account account = new Account();
            account.setName("fhwwww");
            account.setMoney(2500f);
            accountService.saveAccount(account);
        }
    
        @Test
        public void testFindById(){
    //        获取 容器
            ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
    //
            IAccountService accountService = ac.getBean("accountService", IAccountService.class);
    //       要跟新 的那条信息
        } @Test
        public void testUpdate(){
    //     获取 容器
            ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
    //
            IAccountService accountService = ac.getBean("accountService", IAccountService.class);
    //       要跟新 的那条信息
            Account account4= accountService.findById(5);
            account4.setName("f001");
            account4.setMoney(22222f);
            accountService.updateAccount(account4);
    
        } @Test
        public void testDelete(){
    //     获取 容器
            ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
    //
            IAccountService accountService = ac.getBean("accountService", IAccountService.class);
    //        Account account4 = accountService.findById(4);
            accountService.deleteAccount(5);
        }
    
    
    }
    
    

    有了案例的加持 ======= 一起 回顾 这些注解 的

    图解 -这些 注解的 总结 : ===============

    在这里插入图片描述

    在这里插入图片描述

    这是扫描 包 主机的 底层的实现 :================

    在这里插入图片描述

    这是 @Bean ======= 注解的的底层实现

    在这里插入图片描述

    @Bean 在引入数据源的 注解 :

    引入之前 :

    在这里插入图片描述

    引入之后 : 的对照 可以参考的是 : 子配置类 : DataConfig

    在这里插入图片描述

    配置类的注解 与源码: @Configuration

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    使用的 注解 : 定义 配置注解的的类 @Configuration

    要么写在AnnotionConfigApplicationContext的参数里

    要么 在该 配置类 使用 @Configuration

    子配置类 使用注解 @Import (类名.class)

    在这里插入图片描述

    最总 回到运行终于测试 结果

    在这里插入图片描述

    spring与 junit 的这从一开始 就是这样 的 套路 :

    首先我们要分析的 是 : 作为专项的测试 人员 : 要应有的专项 :

    在团队 的开发中的 工作的 业务 也 要 像 我们认识到的 这款框架一样 :=== 解耦合

    在这里插入图片描述
    在这里插入图片描述

    现在 想要期望的是 : 将原本不能 加载 IOC 容器 的 换做一个 可以执行的

    ====== 加的额是 Spring 的依赖的坐标 :

    <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-test</artifactId>
                    <version>5.0.2.RELEASE</version>
                </dependency>
    

    用junit 的@

    在这里插入图片描述

    告知spring 运行器IOC 是基于 XML还是 注解的

    @ Configuration

    location : 指定 的是 xml 文件的 加上 classPath:位置 就 标识在类路径下

    classes :指定注解所在位置 代表用注解 创建

    spring5.x 的时候 要求Junit 的版本是4.12 以上

    
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.12</version>
                </dependency>
    

    #### 不然这里就会 出错 :
    /* 如何确保 这些 全部都能 执行 增删改查 都能执行 先执行 加一条数据 就好多了 */

    package com.fhw.test;
    
    import com.fhw.config.SpringConfiguration;
    import com.fhw.pojo.Account;
    import com.fhw.service.IAccountService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    /*   @ Configuration  dde
    *   location : 指定 的是  xml 文件的 加上classPath:位置 就 标识在类路径下
    *    classes :指定注解所在位置 代表用注解 创建
    *    spring5.x 的时候 要求Junit 的版本是4.12 以上
    *
    *   */
    import java.util.List;
    @RunWith(SpringJUnit4ClassRunner.class)
    //获取 容器  ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
    @ContextConfiguration(classes = SpringConfiguration.class)
    public class AccountTest {
    
        //注入容器  IAccountService accountService = ac.getBean("accountService", IAccountService.class)
    /* 如何确保  这些  全部都能 执行    增删改查 都能执行      先执行  加一条数据   就好多了    */
        @Autowired
        private IAccountService as = null;
        @Test
        public void testFindAll() {
            //3.执行方法
            List<Account> accounts = as.findAllAccount();
            for(Account account : accounts){
                System.out.println(account);
            } }
        @Test
        public void testFindOne() {//3.执行方法
            Account account = as.findAccountById(1);
            System.out.println(account);
        }
        /*  先执行  加一条数据   就好多了   */
        @Test
        public void testSave() {
            Account account = new Account();
            account.setName("test anno");
            account.setMoney(12345f);//3.执行方法
            as.saveAccount(account);
        }
        @Test
        public void testUpdate() {//3.执行方法
            Account account = as.findAccountById(9);
            account.setMoney(23456f);
            as.updateAccount(account);
        }
        @Test
        public void testDelete() {//3.执行方法
            as.deleteAccount(7);
        }
    }
    
    
    

    ======== 最后圆满的答案 ========

    在这里插入图片描述

    spring 整合 xml junit完成 的 ###

    展开全文
  • ...  at org.apache.catalina.deploy.WebXml.addServletMapping(WebXml.java:293)  at org.apache.catalina.startup.ContextConfig.processAnnotationWebServlet...原因:注解的名称与web.xml配置的 名称一样

    Caused by: java.lang.IllegalArgumentException: The servlets named [FindWordServlet] and [com.heima.servlet.FindWordServlet] are both mapped to the url-pattern [/FindWordServlet] which is not permitted
        at org.apache.catalina.deploy.WebXml.addServletMapping(WebXml.java:293)
        at org.apache.catalina.startup.ContextConfig.processAnnotationWebServlet(ContextConfig.java:2410)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2085)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsFile(ContextConfig.java:2046)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsFile(ContextConfig.java:2039)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsFile(ContextConfig.java:2039)
        at org.apache.catalina.startup.ContextConfig.processAnnotationsFile(ContextConfig.java:2039)
        at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1304)
        at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:889)
        at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:386)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5380)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        ... 6 more

    原因:注解的名称与web.xml配置的 <url-pattern>名称一样

    展开全文
  • servlet的两种开发方式【xml注解】-笔记》 Web基础课程介绍 Tomcat&Servlet 请求对象 响应对象和上下文对象 Cookie&Session JSP 过滤器&监听器 综合练习(1. mysql, 2. mybatis 3. 前端 ...

    《Tomcat安装、配置&项目的3种发布方式&IDEA配置tomcat&servlet的两种开发方式【xml、注解】-笔记》

    Web基础课程介绍

    1. Tomcat&Servlet

    2. 请求对象

    3. 响应对象和上下文对象

    4. Cookie&Session

    5. JSP

    6. 过滤器&监听器

    7. 综合练习(1. mysql, 2. mybatis 3. 前端 4. servlet)

    学习目标

    1. Tomcat的使用
      1. 能够理解WEB服务器
      2. 能够运用Tomcat服务器部署WEB项目
      3. 能够使用idea编写Servlet
      4. 能够使用idea配置Tomcat方式发布项目
    2. 编写Servlet
      1. 能够使用注解开发Servlet
      2. 能够说出Servlet生命周期
      3. 能够说明Servlet的执行原理

    学习内容

    1. 软件的架构:BS和CS

    目标

    1. 什么是BS
    2. 什么是CS

    BS和CS概述

    • CS(Client/Server):客户端/服务器模式,程序是运行在客户端,客户端也可访问服务器上的数据库。
    • BS(Browser/Server):浏览器/服务器模式,程序是运行在服务器上。用户通过浏览器来访问我们写的代码。

    CS特点

    软件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h52gt1U8-1598527638455)(assets/1552379873269.png)]

    大型游戏

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-miQubPPk-1598527638472)(assets/1552379995450.png)]

    1. 用户在本地电脑上要安装软件,现在所有的手机APP都是CS结构。
    2. 如果服务器进行升级,客户端也必须要进行升级。
    3. 程序员的开发工作量主要在客户端
    1552380039467

    BS特点

    企业管理软件

    所有要有通过浏览器来访问的软件,都称为BS结构。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oNMAQuxQ-1598527638485)(assets/1552380075819.png)]

    1. 客户端使用浏览器就可以了
    2. 如果服务器端进行了升级,客户端不需要升级就可以访问
    3. 程序员开发工作量主要在服务器,我们就是写服务器端的程序员,使用java来开发。

    小结

    1. 什么是BS?Browser Server 浏览器服务器模式
    2. 什么是CS?Client Server 客户端服务器模式

    2. Web资源的分类:静态和动态

    目标

    Web资源分成哪两类

    分类依据

    1. 分成:静态资源和动态资源。如何区分静态或是动态资源呢?
    2. 标准:程序是否运行在服务器端,如果运行在服务器端这是动态资源,如果运行在浏览器端这是静态资源。

    静态网站的特点:

    使用的技术:HTML,CSS,JavaScript 这些都是运行在浏览器端。

    如果没有人去修改或更新这个网页,它永远是一成不变的。

    动态网站的特点:

    1. 数据是保存在数据库中
    2. 功能上能够实现静态网站不能实现的功能,如:登录,挂号,下订单
    3. 我们在浏览器端看到的网页,其实是服务器端程序运行的结果。
    4. 使用的技术:Servlet,JSP,AJAX等

    小结

    Web资源分成哪两类?

    1. 静态资源
    2. 动态资源

    3. 什么是Web服务器

    目标

    什么是Web服务器

    什么是Web服务器

    1. 又叫Web容器,容器中装的是我们写的Java程序。Web容器也是用Java语言写的,它会调用我们写的Java程序。以后我们写的Java程序没有main函数。我们写的程序要符合Web容器的要求。

    2. 实现数据共享的功能,将服务器上的数据分享给其他的用户。

    3. 访问方式:通过请求和响应的方式来实现的。

      image-20200827095357950

    JavaEE规范

    Java语言分为三种:

    1. JavaSE:标准版(以前我们学的)
    2. JavaEE:企业版(我们学的)
    3. JavaME:移动版(很少使用)

    JavaEE是有一种规范,由13种规范组成,Web容器就会实现这些规范。就可以运行我们写的JavaEE的程序。

    在Java中所有的服务器厂商都要实现一组Oracle公司规定的接口,这些接口是称为JavaEE规范。

    不同厂商的JavaWeb服务器都实现了这些接口,实现的规范越多,功能越强。

    常见的Web服务器

    WebLogic

    ​ WebLogic是Oracle公司的产品,是目前应用最广泛的Web服务器,支持J2EE规范。WebLogic最早由 WebLogic Inc. 开发,后并入BEA 公司,最终BEA公司又并入 Oracle公司。BEA WebLogic是用于开发、集成、集群、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nm7VvORe-1598527638530)(assets/1552381082395.png)]

    WebSphere

    ​ 另一个常用的Web服务器是IBM公司的WebSphere,支持JavaEE规范。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XpICkUXY-1598527638534)(assets/1552380951862.png)]

    其它中小型服务器

    1552380988233

    今天主角:Tomcat

    ​ 在小型的应用系统或者有特殊需要的系统中,可以使用一个免费的Web服务器:Tomcat。支持的规范:该服务器支持全部JSP以及Servlet规范。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ELsJu1uz-1598527638537)(assets/1552381020336.png)]

    小结

    1. Web服务器是什么?
      1. 又叫Web容器,我们的程序运行在Web容器中
    2. 说出三个常用的Web服务器
      1. tomcat
      2. weblogic
      3. glass fish

    4. Tomcat的安装、配置【重点】

    目标

    1. tomcat的安装
    2. 环境变量的配置

    下载页面

    tomcat的产品页面: http://tomcat.apache.org/

    1552386691227

    安装

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BK8nxlTq-1598527638539)(assets/1552386751732.png)]

    将压缩包直接解压到任意一个目录就可以了

    注:

    1. 不要放在中文目录下
    2. 目录层次不要太深
    3. 要有全部的访问权限

    环境变量的配置

    1. 添加Tomcat的安装目录

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Rzmr7sR-1598527638546)(assets/1552386800008.png)]

    2. 配置Path,可以在任何路径下访问bin文件夹的可执行文件

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BWbcJG5n-1598527638547)(assets/1552386873573.png)]

    小结

    1. tomcat如何安装?

      直接解压就可以了

    2. 需要配置哪两个环境变量?

      CATALINA_HOME=安装目录
      Path=%CATALINA_HOME%\bin;
      可以在任意路径下直接运行bin目录下可执行文件
      

    5. Tomcat的启动与关闭

    目标

    1. 启动与关闭tomcat的命令
    2. Tomcat每个目录的作用

    启动与关闭命令

    在命令行窗口下执行,不建议去双击。可执行文件在bin目录下:

    1. 启动的命令:startup.bat

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-98FVPyJF-1598527638549)(assets/image-20200827101921278.png)]

      在浏览器上看到的结果:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTCQMwDX-1598527638551)(assets/image-20200827101904117.png)]

    2. 关闭的命令:shutdown.bat

      tomcat的窗口就会自动关闭

    Tomcat的目录结构

    目录名 作用
    bin 可执行文件所在的目录,如:startup.bat
    conf tomcat的配置目录,其中:server.xml是它的核心配置文件
    lib 就是tomcat依赖的第三方jar包
    logs 日志记录文件,文本文件,管理员用来查看服务器运行的情况
    temp 临时目录,用来保存tomcat运行过程中生成的垃圾文件
    webapps 我们的项目部署在这个目录下
    ROOT目录:我们输入http://localhost:8080看到的网页就在这里
    work tomcat在执行项目过程中工作目录,如:JSP生成Java代码在这里

    如果控制台有乱码解决方法如下

    1. 修改conf/logging.properties文件

    2. 把所有的UTF-8换成GBK

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vpgmUPeJ-1598527638552)(assets/image-20200827102255736.png)]

    3. 重启服务器后,没有乱码了

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lyF6O8i6-1598527638557)(assets/image-20200827102338545.png)]

    扩展:查看Tomcat的源码

    找Bootstrap.java文件,约436行可以看到main函数,这是tomcat的入口

    public static void main(String args[]) 
    

    小结

    1. tomcat的启动和关闭的命令是什么?

      startup.bat shutdown.bat

    2. bin和webapps目录的作用是什么?

      1. bin:可执行文件所在的目录
      2. webapps:项目部署的目录

    6. Tomcat启动时常见的问题

    目标

    启动时常见的两个问题

    问题1:未设置Path或Path的路径错误

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dOgKJf7q-1598527638559)(assets/image-20200827104922617.png)]

    检查Path环境变量,看路径是否配置正确

    %CATALINA_HOME%\bin;
    

    问题2:未设置JAVA_HOME环境变量

    注:JDK使用1.8的版本,不要使用11的版本。查看JDK的版本:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wwvY4SbL-1598527638561)(assets/image-20200827105107216.png)]

    1. 出错信息

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nXj9nW8K-1598527638563)(assets/image-20200827105721986.png)]

    运行tomcat必须要配置JAVA_HOME或JRE_HOME这个环境变量

    1. 解决办法

    把JAVA_HOME配置正确就可以了

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NwCqj1N7-1598527638566)(assets/image-20200827105914190.png)]

    问题3:端口号被占用

    注:tomcat默认的端口号是8080,如果这个端口被其它程序占用,会导致tomcat启动失败。

    1. 出错信息

    2. 查看日志文件:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DXqbHKp8-1598527638567)(assets/image-20200827110202659.png)]

    3. 解决方法:使用一个软件CurrPorts,可以看查看所有的端口占用的情况

      1. 方法一:找到占用端口号的程序,进程杀掉。

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRobDWhk-1598527638569)(assets/1552387382007.png)]

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YTUqj1Tm-1598527638570)(assets/image-20200827110437802.png)]

      2. 方法二:修改tomcat的端口号

        1. 修改conf/server.xml文件

        2. 找到69行,修改端口号

          <Connector port="8888" protocol="HTTP/1.1"
          		   connectionTimeout="20000"
          		   redirectPort="8443" />
          
        3. 重新启动tomcat,新的端口才起作用

          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5XnpouMJ-1598527638571)(assets/image-20200827110736533.png)]

        4. 浏览器的访问地址:http://localhost:8888

          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lKmlgSXK-1598527638573)(assets/image-20200827110801576.png)]

    小结

    常见的问题有哪三个?如何解决?

    1. 输入startup.bat提示命令找不到?

      path环境变量配置错误
      
    2. 输入startup.bat,提示JAVA_HOME没有配置

      添加JAVA_HOME的变量
      
    3. 端口号被占用

      1. 找到占用8080的端口程序,终止
      2. 修改tomcat的端口号为别的
      

    7. Tomcat项目发布的三种方式【重点】

    目标

    tomcat项目发布的三种方式

    发布方式1:复制到webapps

    操作方法

    直接将项目复制到webapps目录下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p2QqVZwO-1598527638574)(assets/image-20200827111308262.png)]

    访问地址:http://localhost:8080/heima/index.html

    image-20200827111422884

    发布方式2:虚拟目录

    上面部署的缺点:会导致webapps目录下项目越来越多,不利于管理,影响启动速度。

    这种方式的好处:不需要复制到webapps目录下,只要配置一个虚拟目录,指向服务器硬盘上一个目录就可以了。

    配置方式

    conf/server.xml中host元素下,放在167行比较好。常见的错误:标签后面没有/>

    代码

      <!-- 
      虚拟路径的配置
      path:指定在浏览器上的访问路径
      docBase:指定本地硬盘的真实路径
      配置完毕后要重启服务器
      -->
      <Context path="/heima" docBase="e:/heima"/>
    

    浏览器上测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-decgMZnZ-1598527638575)(assets/image-20200827112104686.png)]

    发布方式3:独立的XML文件

    1. 在tomcat/conf/catalina/localhost中创建xml配置文件

    2. 名称假设为:second.xml,这个名称就是项目的访问路径

    3. 添加xml文件的内容为

      <!-- 
      虚拟路径的配置
      docBase:指定本地硬盘的真实路径
      配置完毕后不需要重启服务器
      -->
      <Context docBase="e:/heima"/>
    

    浏览器上测试

    http://localhost:8080/second/index.html

    小结

    方式1:直接复制项目到webapps下

    方式2:修改server.xml文件,添加Context元素

    方式3:在conf/catalina/localhost创建一个xml文件,内容是Context,文件名就是访问地址。

    8. 在idea中配置Tomcat【重点】

    目标

    1. 在idea中创建一个静态网站
    2. 配置tomcat,部署静态网站运行

    在idea中创建web项目

    1. 确认项目配置是否正确

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y0Eu04uI-1598527638577)(assets/image-20200827112916447.png)]

    2. 创建一个新的Web模块

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ENIzXi2q-1598527638579)(assets/image-20200827113040499.png)]

    3. 要配置tomcat服务器

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0RJ5qNo-1598527638581)(assets/image-20200827113108218.png)]

    4. 选择Tomcat服务器

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qQ6Kf9sG-1598527638582)(assets/image-20200827113132362.png)]

    5. 指定tomcat的安装目录

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zI9kHOct-1598527638583)(assets/image-20200827113213471.png)]

    6. 给新的模块起名

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-caBidzbB-1598527638584)(assets/image-20200827113250758.png)]

    7. 新创建的模块目录结构

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HXcz6R5E-1598527638585)(assets/image-20200827113350002.png)]

    发布自己的项目

    1. 复制heima下面这一级目录复制到web目录下

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3gBHWDP-1598527638587)(assets/image-20200827113518132.png)]

    2. 复制后的web目录
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-heMraWLb-1598527638588)(assets/image-20200827113600875.png)]

    3. 只要创建的是web项目,idea就已经自动部署到tomcat中了,点这个按钮就可以直接运行了。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2jLgR2E-1598527638589)(assets/image-20200827113813461.png)]

    4. 浏览器会自动打开当前的项目

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQHJdCAi-1598527638591)(assets/image-20200827113955342.png)]

    idea中配置tomcat

    我们要将idea和tomcat集成到一起,可以通过idea就控制tomcat的启动和关闭

    1. 如果在tomcat中没有项目,前面会有一个x

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6CnOAB9b-1598527638592)(assets/image-20200827114121601.png)]

    2. 配置服务器的详细信息

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gN5QyWhl-1598527638594)(/assets/1552390413507.png)]

    1. 修改项目发布的访问地址

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E5BSB0kr-1598527638596)(/assets/1552390423678.png)]

    1. 选项卡的各项参数说明

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bj3rhQj2-1598527638598)(/assets/1552390434381.png)]

    1. 双击左下角可以自动打开浏览器,并且访问项目

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hlLSYYjd-1598527638600)(assets/image-20200827114408038.png)]

    idea的部署方式

    1. 在控制台看到以下几句话

      Using CATALINA_BASE:   "C:\Users\Administrator\.IntelliJIdea2019.1\system\tomcat\Tomcat_8_5_511_JavaEE143"
      
      Using CATALINA_HOME:   "C:\apache-tomcat-8.5.51"
      Using CATALINA_TMPDIR: "C:\apache-tomcat-8.5.51\temp"
      Using JRE_HOME:        "C:\Java\jdk1.8.0_221"
      
    2. 找到第1句话所在的目录

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UrP1dRrH-1598527638601)(assets/image-20200827143642697.png)]

    3. 打开ROOT.xml文件,看到以下内容。docBase就是项目部署的真实地址

      <Context path="" docBase="D:\IdeaWork\JavaEE143\out\artifacts\day26_01_tomcat_war_exploded" />
      
    4. 这个out目录可以在这里设置

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9qz4c4r3-1598527638603)(assets/image-20200827143806605.png)]

    9. XML配置方式:创建Servlet

    目标

    使用web.xml配置方式编写第1个Servlet

    什么是Servlet

    本质上就是一个类,必须要符合一定的规范,运行在Web容器中,对用户从浏览器发送的请求进行处理,并且做出响应。

    Tomcat与Servlet的关系

    image-20200827144155625

    Servlet与普通的Java程序的区别

    1. 本质上就是一个类
    2. 这个类必须实现接口:javax.servlet.Servlet接口
    3. 运行在Tomcat中

    步骤

    1. 创建web工程

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zddmY0Vp-1598527638605)(assets/1552390081885.png)]

    2. 通常web结构如下

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKgVzxE3-1598527638606)(assets/1552390098127.png)]

    3. 如果WEB-INF下没有web.xml,在idea使用以下方法添加web.xml。(注:要加web目录)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1en4anK1-1598527638607)(assets/1552390139905.png)]

    4. 在com.itheima.servlet包下创建一个类Demo1HelloServlet继承于HttpServlet类,并重写doGet()方法。在浏览器上使用打印流输出Hello Servlet!

    注:如果直接在浏览器上输入地址访问Servlet,它调用的是doGet方法

    package com.itheima.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * 创建Servlet的步骤:
     * 1. 创建一个类继承于HttpServlet,这是一个抽象类,它已经实现了Servlet接口
     * 2. 重写doGet或doPost方法,其中doGet用于处理表单的GET请求,doPost用于处理表单的POST请求
     * 3. 在web.xml中配置servlet的访问地址
     */
    public class Demo1Servlet extends HttpServlet {
    
        /**
         * 处理GET请求的方法
         * @param request 请求对象
         * @param response 响应对象
         */
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1. 设置响应的编码和格式
            response.setContentType("text/html;charset=utf-8");
            //2. 通过响应对象获取一个打印流
            PrintWriter out = response.getWriter();
            //3.向浏览器端输出内容
            out.print("<h1>你好,这是我的第一个Servlet</h1>");
        }
    }
    
    
    1. 编辑web.xml中配置servlet,设置访问地址为/demo1
    <servlet>
        <!--servlet的名字-->
        <servlet-name>demo1</servlet-name>
        <!--servlet的完全限定名:包名.类名-->
        <servlet-class>com.itheima.servlet.Demo1Servlet</servlet-class>
    </servlet>
    <!--指定servlet的访问地址-->
    <servlet-mapping>
        <!--这个名字和上面的名字要相同-->
        <servlet-name>demo1</servlet-name>
        <!--指定访问地址,注:必须以/开头 -->
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
    

    小结

    使用XML的方式创建Servlet的主要步骤是什么?

    1. 创建一个类继承于HttpServlet
    2. 重写doGet或doPost方法
    3. 在web.xml中配置访问地址

    10. 注解的方式:开发Servlet【重点】

    目标

    使用注解的方式创建Servlet

    步骤

    1. 创建Servlet类,使用注解@WebServlet

    2. 代码:

      package com.itheima.servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;
      
      /**
       * 1. 创建一个类继承于HttpServlet
       * 2. 重写doGet或doPost方法
       * 3. 使用@WebServlet注解的方式设置访问地址
       *      属性:
       *          name: 表示servlet的名字,不能出现同名的servlet
       *          value:表示访问地址,必须以/开头
       *          urlPatterns: 设置访问地址的,与value功能相同
       */
      @WebServlet("/demo2")
      public class Demo2Servlet extends HttpServlet {
      
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              //1.设置响应类型和编码
              response.setContentType("text/html;charset=utf-8");
              //2.获取打印流
              PrintWriter out = response.getWriter();
              //3.输出内容到浏览器上
              out.print("<h2 style='color:red'>这是注解的Servlet</h2>");
          }
      }
      
      
    3. 点右上角启动按钮执行

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhEcpASq-1598527638610)(assets/1552391203018.png)]

    4. 浏览器上执行效果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18IheBHF-1598527638611)(assets/image-20200827150639311.png)]

    1. 左下角的几个按钮作用

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I5KIMuTk-1598527638612)(assets/image-20200827150553514.png)]

    小结

    说说使用注解编写Servlet的步骤

    1. 创建一个类继承于HttpServlet
    2. 重写doGet或doPost方法
    3. 使用注解@WebServlet("/访问路径")

    11. Servlet的生命周期【重点】

    目标

    Servlet生命周期有哪些方法

    所有的Servlet必须要实现Servlet接口

    public class Demo2Servlet extends HttpServlet
    
    public abstract class HttpServlet extends GenericServlet 
    
    public abstract class GenericServlet implements Servlet
    
    结论:我们写的Servlet其实也是实现了Servlet接口
    

    Servlet接口中的方法

    方法 作用 运行次数
    void init(ServletConfig config) 初始化:在Servlet初始化的时候执行 1次
    void service(ServletRequest req, ServletResponse res) 服务:每次用户发送请求都会执行 多次
    void destroy() 销毁:服务器关闭的时候才执行 1次

    Servlet的生命周期

    注:一个Servlet在tomcat容器中只会实例化一次,只会产生一个对象,而且常驻内存。要等到服务器关闭才会销毁。

    image-20200827151609350

    生命周期演示案例

    效果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WbMH8X88-1598527638614)(assets/image-20200827152250129.png)]

    代码

    package com.itheima.servlet;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebServlet;
    import java.io.IOException;
    
    /**
     * 1.创建一个类实现Servlet接口
     * 2.重写接口中所有的方法,其中与生命周期有关的方法
     *      init() service() destroy()
    *  3.添加@WebServlet注解设置访问地址
     */
    @WebServlet("/demo3")
    public class Demo3LifeCycleServlet implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("执行初始化的方法");
        }
    
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("执行服务的方法");
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
            System.out.println("执行销毁的方法");
        }
    }
    
    

    小结

    1. Servlet是什么时候实例化的?

      用户第一次访问的时候

    2. 一个Servlet在Tomcat中会生成几个对象?

      一个对象

    12. Servlet映射多个路径

    目标

    上面的案例,每个Servlet只有一个访问地址。其实每个Servlet是可以配置多个访问地址的。

    XML方式

    在一个servlet-mapping中可以写多个url-pattern分别指定不同的访问地址

    <servlet>
        <!--servlet的名字-->
        <servlet-name>demo1</servlet-name>
        <!--servlet的完全限定名:包名.类名-->
        <servlet-class>com.itheima.servlet.Demo1Servlet</servlet-class>
    </servlet>
    <!--指定servlet的访问地址-->
    <servlet-mapping>
        <!--这个名字和上面的名字要相同-->
        <servlet-name>demo1</servlet-name>
        <!--指定访问地址,注:必须以/开头 -->
        <url-pattern>/demo1</url-pattern>
        <url-pattern>/demo100</url-pattern>
    </servlet-mapping>
    

    注解方式

    value和urlPatterns参数其实是字符串数组,可以指定多个访问地址

    @WebServlet({"/demo2","/demo200"})
    @WebServlet(urlPatterns = {"/demo20","/demo2000"})
    

    小结

    1. XML方式:写url-pattern的访问地址
    2. 注解方式:@WebServlet中value或urlPatterns参数是一个字符串数组

    13. url-pattern的通配符

    目标

    Servlet的访问地址是支持*号做为通配符

    介绍

    1. 什么是通配符:使用*可以匹配任意多个字符

    2. 两种通配符的格式:

    通配符格式 说明
    /开头 /* 输入任何一个地址都可以访问
    /目录名/* 访问某个目录下的路径
    *.扩展名 访问某个扩展名结尾的地址,如:*.do

    访问原则

    1. 最佳匹配原则,哪个地址最接近就访问哪个

    2. /开头的地址优先于扩展名结尾的地址

    3. /开头和扩展名结尾的地址不能同时出现,同时出现会导致tomcat启动失败

    Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> [/*.do] in servlet mapping
    

    面试题

    创建2个Servlet,一个Servlet1,一个Servlet2,在下列情况下,访问哪个Servlet

    请求URL Servlet1 Servlet2 访问哪个
    /abc/a.html /abc/* /* servlet1,最佳匹配原则
    /abc /abc/* /abc servlet2,最佳匹配原则
    /abc/a.do /abc/* *.do servlet1,/开头优先
    /a.do /* *.do servlet1,/开头优先
    /xxx/yyy/a.do /* *.do servlet1,/开头优先

    小结

    • 优先级:/开头优先于扩展名结尾
    • 匹配原则:最佳匹配原则,哪个最接近就访问哪个

    14. 继承于GenericServlet【了解】

    目标

    通过继承于GenericServlet编写Servlet

    Servlet继承结构

    public class 我们写的Servlet extends HttpServlet
    
    public abstract class HttpServlet extends GenericServlet 
    
    public abstract class GenericServlet implements Servlet,ServletConfig
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y7GMZC4E-1598527638617)(assets/1552393738408.png)]

    继承GenericServlet实现Servlet

    步骤

    1. 创建一个类继承于GenericServlet
    2. 重写的方法是:service(),测试:输出request和response对象
    3. 使用注解@WebServlet设置访问地址

    代码

    package com.itheima.servlet;
    
    import javax.servlet.GenericServlet;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /*
    1. 创建一个类继承于GenericServlet
    2. 重写service方法(生命周期的方法)
    3. 使用@WebServlet注解设置访问地址
     */
    @WebServlet("/demo5")
    public class Demo5Servlet extends GenericServlet {
        /*
        ServletRequest:请求  HttpServletRequest 是它的子接口
        ServletResponse:响应  HttpServletResponse 是它的子接口
         */
        @Override
        public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.print("继承于GenericServlet");
        }
    }
    
    

    小结

    service方法中request和response对象是接口,它的实现类从哪里来的?

    因为是tomcat调用我们写的方法,这两个参数是由Tomcat创建
    
    请求对象:org.apache.catalina.connector.RequestFacade@26559f7c
    响应对象:org.apache.catalina.connector.ResponseFacade@289265c6
    
    查看Tomcat的源码:
    public class RequestFacade implements HttpServletRequest
    

    15. Servlet的执行流程

    目标

    了解tomcat的执行过程

    Tomcat的执行过程

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dW5wvNdk-1598527638618)(assets/image-20200827161824575.png)]

    执行步骤

    1. 在浏览器上输入访问地址: http://localhost:8080/one/demo1
    2. 通过8080找到tomcat
    3. 通过one找到项目
    4. 通过demo1找到Servlet
    5. 找到Servlet以后,通过反射创建对象
    6. 再创建request和response对象,调用service()方法
    7. 由service方法调用doGet或doPost方法
    8. 我们的代码写在doGet或doPost方法中就可以了

    小结

    1. Servlet对象是通过什么技术实例化的?反射
    2. 我们在浏览器上看到的动态网页是怎么来的?就是servlet打印的结果

    16. ServletConfig接口【了解】

    目标

    1. ServletConfig的作用和方法
    2. load-on-startup参数

    作用

    读取web.xml配置文件中初始化参数值

    之前出现在哪个方法中?init(ServletConfig config) 这个对象也是由Tomcat创建的,在初始化的时候就传入了。

    为什么要配置初始化参数

    有些初始化的参数如果直接写死在Java源代码中,不方便以后修改和维护,可以把初始的参数放在web.xml中

    就需要一个对象去读取这些参数,这个对象就是ServletConfig对象。

    因为我们的Servlet已经继承于ServletConfig,就可以直接使用这个接口中方法

    案例:读取配置文件中信息

    需求

    1. 在web.xml中创建一个Servlet
    2. 配置姓名和年龄2个属性
    3. 读取信息,在Servlet上显示出来
    4. 输出所有配置信息的名字和值

    代码

    web.xml

    <servlet>
        <servlet-name>demo6</servlet-name>
        <servlet-class>com.itheima.servlet.Demo6ConfigServlet</servlet-class>
        <!--配置一个初始参数-->
        <init-param>
            <!--参数名-->
            <param-name>user</param-name>
            <!--参数值-->
            <param-value>NewBoy</param-value>
        </init-param>
        <init-param>
            <param-name>age</param-name>
            <param-value>20</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo6</servlet-name>
        <url-pattern>/demo6</url-pattern>
    </servlet-mapping>
    

    servlet代码

    package com.itheima.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    
    public class Demo6ConfigServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //子类继承了父类ServletConfig中方法,可以直接使用
            String user = getInitParameter("user");
    
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.print("你的名字是:" + user + "<hr/>");
    
            //获取所有的参数名,这是一个枚举类,类似于迭代器
            Enumeration<String> names = getInitParameterNames();
            //遍历元素,判断是否还有下一个元素
            while(names.hasMoreElements()) {
                //如果有就获取这个元素,并且向下移动一个位置
                String name = names.nextElement();  //每个参数名
                //通过参数名获取参数值
                String value = getInitParameter(name);
                //打印到浏览器
                out.print("参数名:" + name + ",参数值:" + value + "<hr/>");
            }
        }
    }
    
    

    效果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NpyRt4Cp-1598527638619)(assets/image-20200827170315063.png)]

    小结

    ServletConfig接口中的方法 功能
    String getInitParameter(“参数名”) 通过参数名获取参数值
    Enumeration<String> getInitParameterNames() 获取所有的参数名,返回一个枚举对象,类似于迭代器

    17. load-on-startup参数

    目标

    学习load-on-startup参数使用

    作用

    1. 为什么要使用这个配置?

    默认Servlet什么时候实例化?用户第一次访问的时候实例化。

    有时我们希望Tomcat启动的时候就加载这个Servlet就需要设置这个参数

    1. 参数的使用说明:

    参数的取值是一个整数,设置成0或正整数,这个数越小就越先加载,不能设置成负数,负数和没有设置是一样的。

    案例

    需求

    在一个Servlet中的init方法中直接输出一句话到控制台上,比较加不加的<load-on-startup>的区别

    代码

    web.xml

    <servlet>
        <!--servlet的名字-->
        <servlet-name>demo1</servlet-name>
        <!--servlet的完全限定名:包名.类名-->
        <servlet-class>com.itheima.servlet.Demo1Servlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <!--指定servlet的访问地址-->
    <servlet-mapping>
        <!--这个名字和上面的名字要相同-->
        <servlet-name>demo1</servlet-name>
        <!--指定访问地址,注:必须以/开头 -->
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
    

    servlet

    @WebServlet(urlPatterns = "/demo3", loadOnStartup = 1)
    

    效果

    demo1被加载
    执行初始化的方法
    

    小结

    load-on-startup参数的作用是什么?

    在服务器启动的时候就加载这个Servlet
    

    学习总结

    1. 能够理解WEB服务器

      1. 作用:
        1. 调用我们写的Servlet
        2. 共享资源
      2. 我们使用:tomcat
    2. 能够运用Tomcat服务器部署WEB项目

      1. 直接复制到webapps下
      2. 虚拟路径:修改server.xml,配置Context
      3. 独立的XML文件:在conf/catalina/localhost/文件名.xml 文件名就是访问地址
    3. 能够使用idea编写Servlet

      1. 创建一个类,继承于HttpServlet
      2. 重写doGet或doPost方法
      3. 配置web.xml或使用注解@WebServlet,配置访问地址
    4. 能够使用idea配置Tomcat方式发布项目

    5. 能够使用注解开发Servlet

      @WebServlet属性 说明
      name servlet的名字,不能同名
      urlPatterns 访问地址,字符串数组
      value 同上
      loadOnStartup 服务器启动的时候就加载这个Servlet,数字越小越先加载
    6. 能够说出Servlet生命周期

      方法 作用 运行次数
      void init(ServletConfig config) 初始化的方法 执行1次
      void service(ServletRequest req, ServletResponse res) 服务的方法 每次请求都会执行
      void destroy() 销毁的方法 服务器关闭的时候执行1次
    7. 能够说出Servlet的执行原理

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-06SSbrYJ-1598527638620)(assets/image-20191205175825633.png)]

    展开全文
  • Servlet3.0作为J2EE6.0规范的一部分,随J2EE6.0一起发布,并且Tomcat7.0已经完全支持Servlet3.0. 查看代码: ...无需web.xml配置文件。 转载于:https://www.cnblogs.com/Shunia123/p/10647897.ht...
  • SSM脚手架项目(全注解配置) 根据现在流行的趋势,开发人员越来越喜欢使用注解去配置项目,而不是去使用 xml 文件了。 本 项目便是使用全注解配置,搭建一个基本的 SSM 脚手架项目 配套博文 SSM整合配置全使用注解 ...
  • 记一次错误,tomcat中出现这个问题的原因,是maping和@webServlet的不能同时配置,如果同时配置就会出现以下错误在servlet3.0后使用eclipse中只需要用@webServlet(description="",urlpatterns={"&...
  • Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。 将来我们自定义一个类,实现Servlet接口,复写方法。 一、XML执行原理 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问...
  • Servlet配置web.xml后导致无法启动Tomcat

    千次阅读 2017-11-19 18:08:35
    然后又配置了web.xml中的标签,导致了无法启动Tomcat,原因是因为较新的版本有了新的一项功能,叫注解,如图所示,注解即可以不用再去配置web.xml,不然就会冲突,导致无法启动Tomcat,解决方案是去掉注解或者去掉...
  • tomcat下servlet配置

    2020-07-29 22:12:50
    文章目录servlet读取jsp数据的hello采用web.xml的配置采用注解配置小结 一般在tomcat中配置servlet的方法有两种: 采用web.xml的配置 采用注解配置 在下面的文章中,将一一阐述,不过在开始本文之前,先看下Tomcat...
  • Servlet的生命周期和注解配置问题 /* Servlet? ... 运行在服务器上的小程序 定义浏览器访问到Tomcat的规则 ... 1.... 2.... 3.... 二、servlet3.0注解配置?... 直接在java中注解配置, 可以不需要web.xml 三、servle...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 846
精华内容 338
关键字:

tomcat注解配置xml