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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 哈哈大圣 中级黑马   /  2018-12-19 15:29  /  645 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

# Servlet applet

  • ## 一、Servlet的概念以及入门

> Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则;我们需要自定义类,实现Servlet接口复写方法。

  • ## 入门案例步骤
1. 创建JavaEE项目
2. 建一个包,定义一个类,实现Servlet中的接口
    - `void destroy()`: 服务被关闭之前执行一次,用于释放资源
    - `ServletConfig getServletConfig()`: 获取Servlet的配置对象
    - `void init(ServletConfig config)`: 服务启动或者第一次访问时被创建,初始化
    - `void service(ServletRequest req, ServletResponse res)`:处理请求
    - `String getServletInfo()`: 获取Servlet的版本,作者等信息。
```
// 在service中添加一句
System.out.println("某个浏览器在访问我!");
```

3. 根据约束配置`web.xml`:【得写在根标签里面】
```
    <servlet>
        <servlet-name>Server</servlet-name>
        <servlet-class>cn.lc.server.Server</servlet-class> -- 全类名
    </servlet>

    <servlet-mapping>
        <servlet-name>Server</servlet-name>
        <url-pattern>/server</url-pattern> -- 虚拟路径
    </servlet-mapping>
```


## 二、Servlet执行流程

@@@@@@@@@@@@@@@@@@@@@@@@@@@ Servlet执行原理.bmp

1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
2. 查找web.xml文件,是否有对应的`<url-pattern>`标签体内容。
3. 如果有,则在找到对应的`<servlet-class>`全类名
4. tomcat会将字节码文件加载进内存,并且创建其对象【反射机制】
5. 调用其方法--`service`

## 三、Servlet的生命周期方法【vue中的钩子函数也是这样干的】
1.  **`init`**:被创建:执行 **`init`** 方法,只执行一次。【初始化方法嘛!】
    - Servlet创建时机:
        - 默认情况下,第一次被访问时Servlet被创建
        - 可以手动配置执行Servlet的创建时机【在`<servlet>`标签下配置】
            1. 第一次被访问时创建:`<load-on-startup>-1</load-on-startup>`的值为负数
            2. 在服务器启动时创建:`<load-on-startup>0</load-on-startup>`的值为非负数
    - Servlet的init方法,只能执行一次,Servlet在内存中只存在一个对象,**Servlet是单例模式的**!
        - 多个用户同时访问时,可能存在线程安全问题。
        - **为了防止线程安全问题,尽量不要在Servlet中定义成员变量,如果非要定义,也不要去修改值!**

2. **`service`**:提过服务的方法,**`service`**,每次接受到相关请求,这个方法都会被调用来处理请求

3.  **`destroy`**:被销毁执行此方法,只执行一次
    1. Servlet被销毁时执行。服务器关闭是,Servlet被销毁
    2. 只有服务器正常关闭时,才会执行destroy方法
    3. destroy方法在Servlet被销毁之前执行,一般用于释放资源。

## 四、Servlet3.0介绍

> **支持注解配置。可以不需要`web.xml`了**。

### 使用步骤
1. 创建JavaEE项目,选择Servlet3.0及以上,不用勾选创建`web.xml`
2. 定义一个类,实现Servlet接口
3. 复写方法
4. 在类的上面添加`@WebServlet`注解,进行配置【 **原理是通过注解获取使用了该注解的全类名** 】
    -  `@WebServlet("资源路径[对应的路由]")`

> **【通过注解名获取使用了该注解的所有类的全类名的思路】**:递归遍历src路径下的所有包,找到所有的.class文件,获取其文件上的注解,判断是否有对应的注解,如果有则将全类名存入一个列表,最后将这个列表返回即可!
> 估计Tomcat也是使用类似的机制玩儿的。

```
@WebServlet("/index")
public class Index implements Servlet {
...
```

@WebServlet注解【接口】,源码如下
```
@Target({ElementType.TYPE})  //目标可以作用在类上面
@Retention(RetentionPolicy.RUNTIME)// 注解保留在运行时
@Documented // 可以生成文档
public @interface WebServlet {
    String name() default "";  //相当于<Servlet-name>,不用管,只是一个对应的关系
    String[] value() default {};  // 代表urlPatterns()属性配置【注解默认赋值就是给它!】
    String[] urlPatterns() default {}; // 相当于<url-pattern>
    int loadOnStartup() default -1; // 相当于<load-on-startup>
    WebInitParam[] initParams() default {};
    boolean asyncSupported() default false;
    String smallIcon() default "";
    String largeIcon() default "";
    String description() default "";
    String displayName() default "";
}
```

## 五.Servlet的体系结构

**`Servlet`** -*父接口*--
   - **`GenericServlet`** --*子抽象类*--:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可
       - **`HttpServlet`【推荐使用】** --*孙抽象类*--:对http协议的一种封装,封装了用户的请求判断方式【get,post方法】简化操作
           - 定义类继承HttpServlet;
           - 复写doGet/doPost方法即可

- HttpServlet抽象类部分源码
```
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
        ...
            this.doGet(req, resp);
        ...
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    }...
}
```

### 六. Servlet相关配置

#### urlpartten:Servlet访问路径
1. 一个Servlet可以定义多个访问路径【不建议这样写】:`@WebServlet({"/d4","/dd4","/ddd4"})`
2. 路径定义规则
    - ` /xxx`:路径匹配
    - `/xxx/xxx`:多层路径,目录结构
    - `*`:匹配所有,优先级很低【不用】
    - `*.do`:扩展名匹配,【注意:**'*'号前面别加'/'**】


0 个回复

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