0%

注释简化配置

  • Servlet注解简化配置

3.简化配置

3.1 Servlet注解简化配置

  • 分析 oa 项目中的 web.xml 文件:

    • 现在只是一个单表的 CRUD,没有复杂的业务逻辑,很简单的一丢丢功能,web.xml 文件中就有如此多的配置信息。如果采用这种配置方式,对于一个大的项目来说,web.xml 文件会非常庞大,有可能最终会达到几十兆。
    • web.xml 文件中进行 servlet 信息的配置,显然开发效率比较低,每一个都需要配置一下。而且在 web.xml 文件中的配置是很少被修改的,所以这种配置信息能不能直接写到 java 类当中呢?答案是可以的。
  • Servlet3.0 版本之后,推出了各种 Servlet 基于注解式开发。优点是什么?

    • 开发效率高,不需要编写大量的配置信息,直接在 java 类上使用注解进行标注。
    • web.xml 文件体积变小了。
  • 并不是说注解有了之后,web.xml 文件就不需要了:

    • 有一些需要变化的信息,还是要配置到 web.xml 文件中。一般都是“注解+配置文件”的开发模式。
    • 一些不会经常变化修改的配置建议使用注解。一些可能会被修改的建议写到配置文件中。

★注解配置的使用

  • 注解对象的使用格式: @注解名称(属性名=属性值, 属性名=属性值, 属性名=属性值, ...)

  • 通过在 Servlet 类上使用 @WebServlet,来达到等同于在 web.xml 中进行配置的效果。

    @WebServlet 注解中有哪些属性呢?

    • name 属性:用来指定 Servlet 的名字。等同于 <servlet-name>

    • urlPatterns 属性:用来指定 Servlet 的映射路径,可以指定多个字符串。等同于 <url-pattern>

      注意:映射路径是可以有多个的,表明当使用这些映射路径时,调用的都是该 Servlet 的服务

    • loadOnStartUp 属性:用来指定在服务器启动阶段是否加载该 Servlet。等同于 <load-on-startup>

    • value 属性:value 属性的作用等同于 urlPatterns,当注解中只有 Servlet 的映射路径的时候,value 属性名是可以省略的。等同于 <url-pattern>

    注意:不是必须将所有属性都写上,只需要提供需要的,(需要什么用什么)。

    注意:当属性是一个数组,但是如果数组中只有一个元素,则使用该注解的时候,属性值的大括号可以省略

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //@WebServlet(urlPatterns = {"/welcome1", "/welcome2"})
    // 注意:当注解的属性是一个数组,并且数组中只有一个元素,大括号可以省略。
    //@WebServlet(urlPatterns = "/welcome")
    // 这个value属性和urlPatterns属性一致,都是用来指定Servlet的映射路径的。
    //@WebServlet(value = {"/welcome1", "/welcome2"})
    // 如果注解的属性名是value的话,属性名也是可以省略的。
    //@WebServlet(value = "/welcome1")
    //@WebServlet({"/wel", "/abc", "/def"})
    @WebServlet("/welcome")
    public class WelcomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.print("欢迎学习Servlet。");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    package com.f.javaweb.servlet;

    import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebInitParam;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;

    /**
    * @author fzy
    * @date 2023/12/6 11:55
    */
    @WebServlet(name = "hello", urlPatterns = {"/hello1", "/hello2", "/hello3"}, loadOnStartup = 1,
    initParams = {@WebInitParam(name = "username", value = "admin"), @WebInitParam(name = "pwd", value = "123")})
    public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();

    String servletName = this.getServletName();
    out.print("Servlet名称为: " + servletName + "<br/>");

    String servletPath = request.getServletPath();
    out.print("ServletPath为: " + servletPath + "<br/>");

    Enumeration<String> initParameterNames = this.getInitParameterNames();
    while (initParameterNames.hasMoreElements()) {
    String name = initParameterNames.nextElement();
    String value = this.getInitParameter(name);
    out.print(name + " = " + value + "<br/>");
    }
    }
    }

3.2 通过反射获取注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.f.javaweb.annotation;

import jakarta.servlet.annotation.WebServlet;

/**
* @author fzy
* @date 2023/12/6 13:20
*/
public class TestWelcomeServletAnnotation {
public static void main(String[] args) throws Exception {
// 获取WelcomeServlet类对象
Class welcomeServletClass = Class.forName("com.f.javaweb.servlet.WelcomeServlet");
// 判断该类中是否有WebServlet注解
if (welcomeServletClass.isAnnotationPresent(WebServlet.class)) {
// 获取这个类上面的WebServlet注解
WebServlet webServletAnnotation = (WebServlet) welcomeServletClass.getAnnotation(WebServlet.class);
// 获取注解的value属性值
String[] values = webServletAnnotation.value();
for (String value : values) {
System.out.println(value);
}
}
}
}

3.3 使用模板方法设计模式解决类爆炸

  • 上面的注解解决了配置文件的问题。但是现在的 oa 项目仍然存在一个比较臃肿的问题。

    • 一个单表的 CRUD,就写了 6 个 Servlet。如果一个复杂的业务系统,这种开发方式,显然会导致类爆炸(类的数量太大)。
    • 怎么解决这个类爆炸问题?可以使用模板方法设计模式。
  • 怎么解决类爆炸问题?

    • 以前的设计是一个请求对应一个 Servlet 类,1000 个请求就会对应 1000 个 Servlet 类,导致类爆炸。
    • 可以这样做:一个业务对应一个 Servlet 类,一个请求对应 Servlet 类中的一个方法。例如处理部门相关业务的对应一个 DeptServlet、处理用户相关业务的对应一个 UserServlet、处理银行卡卡片业务对应一个 CardServlet。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    package com.bjpowernode.oa.web.action;

    import com.bjpowernode.oa.utils.DBUtil;
    import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    // 模板类
    @WebServlet({"/dept/list", "/dept/save", "/dept/edit", "/dept/detail", "/dept/delete", "/dept/modify"})
    // 模糊匹配
    // 只要请求路径是以"/dept"开始的,就都走这个Servlet。
    //@WebServlet("/dept/*")
    public class DeptServlet extends HttpServlet {
    // 模板方法
    // 重写service方法(并没有重写doGet或者doPost,因为既有GET请求,也有POST请求)
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // 获取servlet path
    String servletPath = request.getServletPath();
    if("/dept/list".equals(servletPath)){
    doList(request, response);
    } else if("/dept/save".equals(servletPath)){
    doSave(request, response);
    } else if("/dept/edit".equals(servletPath)){
    doEdit(request, response);
    } else if("/dept/detail".equals(servletPath)){
    doDetail(request, response);
    } else if("/dept/delete".equals(servletPath)){
    doDel(request, response);
    } else if("/dept/modify".equals(servletPath)){
    doModify(request, response);
    }
    }

    private void doList(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }

    private void doSave(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }

    private void doEdit(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }

    private void doDetail(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }

    private void doDel(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }

    private void doModify(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    }
    }
---------------The End---------------