java web

JavaWeb(一)

一、创建Javaweb项目

配置好jdk,tomcat环境,我的是jdk8,tomcat9

ideal 创建一个普通Java工程

在这里插入图片描述
右键项目,添加Web App扩展
在这里插入图片描述
右上角添加你的配置,就是和你的tomcat联系在一起
在这里插入图片描述
左边选择本地的local Tomcat,在configrue选择你本地安装的tomcat路径
在这里插入图片描述

点击deployment 、点击加号添加扩展,下面那一行就是你浏览器访问的路径,然后点击Apply
在这里插入图片描述

点击sever,配置热部署,你默认的浏览器以及浏览网页
在这里插入图片描述
启动web项目,浏览器显示默认页面
在这里插入图片描述

二、前端数据提交到Java方法里面

web.xml配置前端数据提交到的某个Java类、即是一个继承于HttpServlet,重写了doGet和doPost方法的类
这是通过路径访问Servlet类,/test/hello需要加上你的网页路径

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>ServletTset</servlet-name>
        <servlet-class>com.wang.study.bean.ServeltTest</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletTset</servlet-name>
        <url-pattern>/test/hello</url-pattern>
    </servlet-mapping>
</web-app>

注解写法,Servlet类上面加上@WebServlet注解

@WebServlet(name = "ServletTset",urlPatterns = "/test/hello")

前端页面from表单提交数据,action是提交地址,method是提交方法

<form action="/test/hello" method="post">
    <input name="username" type="text"/>用户名
    <input name="password" type="password"/>密码
    <button type="submit">提交</button>
</form>

Servlet类,通过action提交地址就能找到某个类,method方法名找到doGet或者doPost方法

public class ServletTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取前端传入的数据
        System.out.println("post");
        String name = req.getParameter("username");
        String pwd = req.getParameter("password");
        System.out.println(name+pwd);
        resp.sendRedirect("/views/main.html");
    }
}

与Mybatis联合

1、三层架构
在这里插入图片描述2、pom依赖

<dependencies>
        <!--jsp依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <!--mysql连接jar包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
        </dependency>
        <!--servlet注解依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!--junit单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

    </dependencies>
    <!--    设置资源目录,使其可以读取dao下xml文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

3、dao层、实体类
接口

public interface StudentDao {
    int addStudent(StudentEntity studentEntity);
}

xml

<mapper namespace="com.wang.study.dao.StudentDao">
    <insert id="addStudent" parameterType="com.wang.study.entity.StudentEntity">
        insert into student (id,s_name,age) value (#{sId},#{sName},#{age})
    </insert>
</mapper>

实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentEntity {
    private int sId;
    private String sName;
    private int age;
}

4、mybatis 全局配置文件

<?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=true&amp;serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncode=UTF-8"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </dataSource>
    </environment>
</environments>
<mappers>
    <mapper resource="mapper/StudentDao.xml"></mapper>
</mappers>
</configuration>

5、Mybatis辅助类,主要获取sqlsession

public class MybatisUtli {
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try{
            String resourse = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resourse);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession(){
        //System.out.println(sqlSessionFactory);
        return sqlSessionFactory.openSession();
    }
}

6、service层
接口

public interface StudentService {
    int addStudent(StudentEntity studentEntity);
}

接口实现类

public class StudentServiceImpl implements StudentService {
    SqlSession sqlSession = MybatisUtli.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    @Override
    public int addStudent(StudentEntity studentEntity) {
        int result = studentDao.addStudent(studentEntity);
        sqlSession.commit();
        sqlSession.close();
        return result;
    }
}

7、controller层

@WebServlet(name = "StudentServlet",urlPatterns = "/addStudent")
public class StudentServlet extends HttpServlet {
    private StudentService studentService = new StudentServiceImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*设置乱码*/
        req.setCharacterEncoding("utf-8");
        int id = Integer.parseInt(req.getParameter("id"));
        String name = req.getParameter("name");
        int age = Integer.parseInt(req.getParameter("age"));
        StudentEntity studentEntity = new StudentEntity(id,name,age);
        System.out.println(studentEntity.toString());
        int result = studentService.addStudent(studentEntity);
        if(result > 0){
            resp.sendRedirect("/views/sucessful.html");
        }else{
            resp.sendRedirect("/views/fail.html");
        }
    }
}

8、前端数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/addStudent" method="get">
    <input name="id" type="text"/>学号
    <input name="name" type="text"/>用户名
    <input name="age" type="text"/>年龄
    <button type="submit">提交</button>
</form>
</body>
</html>

9、报错
如果找不到mysql驱动以及资源文件找不到,在output下添加依赖即可
在这里插入图片描述

四、请求处理

1、最原始的方法,response写,lowb的写法

  PrintWriter writer = resp.getWriter();
        writer.println("<html><head><body><h1>DSB123qqwe</h1></body></head></html>");

2、将后台数据传入到一个request中,由于html是静态页面,所以当前就使用jsp,jsp本质就是一个servlet,只不过jsp页面中能编写html以及jsp脚本能写Java
dao、service层新增一个查询所有学生的方法
controller层

@WebServlet(name = "StudentServlet",urlPatterns = "/students")
public class StudentServlet extends HttpServlet {
    private StudentService studentService = new StudentServiceImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*servlet只有一个,mvc中要使用这个servlet进行请求转发*/
        /*即在这个请求中加入method键值对,根据不同的值,进行转发*/
        String method = req.getParameter("method");
        if(method == null || "".equals(method)){
            getAllStu(req,resp);
        }
        else if("getStudent".equals(method)){

        }
    }
    /*查询所有学生*/
    private void getAllStu(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<StudentEntity> list = studentService.getAllStu();
        /*将数据封装在请求里面*/
        req.setAttribute("students",list);
        /*进行页面跳转,然后该页面取出数据*/
        /*这是一个请求转发,url的路径不能发生变化*/
        req.getRequestDispatcher("/views/students.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

前端jsp

<%--
  Created by IntelliJ IDEA.
  User: wyh
  Date: 2021/9/24
  Time: 10:44
  To change this template use File | Settings | File Templates.
--%><%--jsp指令语法导入包--%>
<%@ page import="com.wang.study.entity.StudentEntity" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style>
        table{
            border: 1px;
            width: 100%;
            border-collapse: collapse;
        }
    </style>
</head>
<body>
<%--jsp脚本语法,里面可以编写java程序--%>
<%
    List<StudentEntity> list = (List<StudentEntity>)request.getAttribute("students");
%>

<table>
    <tr>
        <td>学号</td>
        <td>姓名</td>
        <td>年纪</td>
        <td>操作</td>
    </tr>
    <%--for循环取出数据,这里要将td包裹在循环中--%>
    <% for (int i = 0; i < list.size(); i++) {
        StudentEntity u = list.get(i);
    %>
    <%--   <%=变量名 %>  jsp通过变量名取值  --%>
    <tr >
        <td ><%=u.getSId()%></td >
        <td ><%=u.getSName()%></td >
        <td ><%=u.getAge()%></td >
        <td ><a href="/TestMavenWeb/user3?method=getUser&id=<%=u.getSId()%>">修改</a></td >
    </tr >

    <% }%>
</table>
</body>
</html>

3、重定向返回一个新页面,url会发生变化

resp.sendRedirect("/views/main.html")

jsp JSTL标签库和模板引擎
由于jsp不需要过多的Java代码,并且jsp页面主要就是显示数据,
所以servlet

req.setAttribute("students",list);

jsp页面通过${名字}就能取出数据

<h1>${students}</h1>

pom添加依赖,jsp页面加入模板

<!--JSTL标签库-->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

jsp加入模板

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

循环取出数据

<body>
<table>
    <tr>
        <td>学号</td>
        <td>姓名</td>
        <td>年龄</td>
    </tr>
    <c:forEach items="${studnets}" var="student">
        <c:choose>
            <c:when test="${student.id % 2 == 0}">
                <tr style="background-color:#ccc;">
            </c:when>
            <c:otherwise>
                <tr>
            </c:otherwise>
        </c:choose>
        <td>${student.id}</td>
        <td>${student.name}</td>
        <td>${student.age}</td>
        </tr>
    </c:forEach>
</table>
</body>

4、前端通过一个url请求获取数据
业务场景数据表格,点击按钮,获取后台传过来的数据,显示在表格里
一般是将数据打包成json格式给前端
前端需要的数据

{"code":200,"msg":"sucess","count":1000,
"data":[
{"id":10000,"username":"user-0","sex":"女","city":"城市-0"},
{"id":10001,"username":"user-1","sex":"男","city":"城市-1"}]}

code是状态码
msg请求结果
count是数据表格中需要进行分页总数据条数
data是要显示的数据,后端一般是list集合
java servlet类中

List<OInfoEntity> list = orderService.getInfos();
System.out.println(list);
/*通过打印流向前端传输数据*/
/*这里就是传输符合的json数据*/
PrintWriter out = resp.getWriter();
Map<String,Object> resMap = new HashMap<>();    // 使用Map存储键值对
resMap.put("code",200);                         // 向Map对象中添加内容
resMap.put("msg","sucess");
resMap.put("count","10");
String resJSON = JSON.toJSONString(resMap);     // 转换为json
out.print(resJSON);                             // 输出

map转换为json的依赖

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.72</version>
</dependency>

实际项目中,我们通常会封装一个响应类配合分页插件向前端响应数据
R类

/**
 * 返回数据
 *  R 继承了 HashMap 则不能继续使用泛型数据了 必须全是hashMap数据
 */
public class R extends HashMap<String, Object> {

	private static final long serialVersionUID = 1L;

	/**
	 * @param key 获取指定key的名字
	 */
	public <T> T getData(String key, TypeReference<T> typeReference){
		// get("data") 默认是map类型 所以再由map转成string再转json
		Object data = get(key);
		return JSON.parseObject(JSON.toJSONString(data), typeReference);
	}
	/**
	 * 复杂类型转换 TypeReference
	 */
	public <T> T getData(TypeReference<T> typeReference){
		// get("data") 默认是map类型 所以再由map转成string再转json
		Object data = get("data");
		return JSON.parseObject(JSON.toJSONString(data), typeReference);
	}

	public R setData(Object data){
		put("data", data);
		return this;
	}
	public R() {
		put("code", 0);
		put("msg", "success");
	}

	public static R error() {
		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系FIRENAY");
	}

	public static R error(String msg) {
		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
	}

	public static R error(int code, String msg) {
		R r = new R();
		r.put("code", code);
		r.put("msg", msg);
		return r;
	}

	public static R ok(String msg) {
		R r = new R();
		r.put("msg", msg);
		return r;
	}

	public static R ok(Map<String, Object> map) {
		R r = new R();
		r.putAll(map);
		return r;
	}

	public static R ok() {
		return new R();
	}

	public R put(String key, Object value) {
		super.put(key, value);
		return this;
	}

	public Integer getCode() {
		return (Integer) this.get("code");
	}
}

分页工具类

/**
 * 分页工具类
 *
 */
public class PageUtils implements Serializable {
	private static final long serialVersionUID = 1L;
	/**
	 * 总记录数
	 */
	private int totalCount;
	/**
	 * 每页记录数
	 */
	private int pageSize;
	/**
	 * 总页数
	 */
	private int totalPage;
	/**
	 * 当前页数
	 */
	private int currPage;
	/**
	 * 列表数据
	 */
	private List<?> list;
	
	/**
	 * 分页
	 * @param list        列表数据
	 * @param totalCount  总记录数
	 * @param pageSize    每页记录数
	 * @param currPage    当前页数
	 */
	public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
		this.list = list;
		this.totalCount = totalCount;
		this.pageSize = pageSize;
		this.currPage = currPage;
		this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
	}

	/**
	 * 分页
	 */
	public PageUtils(IPage<?> page) {
		this.list = page.getRecords();
		this.totalCount = (int)page.getTotal();
		this.pageSize = (int)page.getSize();
		this.currPage = (int)page.getCurrent();
		this.totalPage = (int)page.getPages();
	}

	public int getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public int getCurrPage() {
		return currPage;
	}

	public void setCurrPage(int currPage) {
		this.currPage = currPage;
	}

	public List<?> getList() {
		return list;
	}

	public void setList(List<?> list) {
		this.list = list;
	}
	
}

参数类

/**
 * 查询参数
 *
 */
public class Query<T> {

    public IPage<T> getPage(Map<String, Object> params) {
        return this.getPage(params, null, false);
    }

    public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
        //分页参数
        long curPage = 1;
        long limit = 10;

        if(params.get(Constant.PAGE) != null){
            curPage = Long.parseLong(params.get(Constant.PAGE).toString());
        }
        if(params.get(Constant.LIMIT) != null){
            limit = Long.parseLong((String)params.get(Constant.LIMIT));
        }

        //分页对象
        Page<T> page = new Page<>(curPage, limit);

        //分页参数
        params.put(Constant.PAGE, page);

        //排序字段
        //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
        String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
        String order = (String)params.get(Constant.ORDER);


        //前端字段排序
        if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
            if(Constant.ASC.equalsIgnoreCase(order)) {
                return  page.addOrder(OrderItem.asc(orderField));
            }else {
                return page.addOrder(OrderItem.desc(orderField));
            }
        }

        //没有排序字段,则不排序
        if(StringUtils.isBlank(defaultOrderField)){
            return page;
        }

        //默认排序
        if(isAsc) {
            page.addOrder(OrderItem.asc(defaultOrderField));
        }else {
            page.addOrder(OrderItem.desc(defaultOrderField));
        }

        return page;
    }
}

五、cookie与session

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session,
由于HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话,所以有会话跟踪技术。
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
简单理解:登陆网站之后,关闭浏览器,下次登陆,就不需要登陆了,这就是会话(Session)跟踪。
使用

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*获取浏览器上所有的cookie*/
        Cookie[] cookies = req.getCookies();
        boolean flag = false;
        if(cookies != null){
            for (Cookie cookie:cookies) {
                /*循环遍历找到名是lastTime的cookie*/
                if(cookie.getName().equals("lastTime")){
                		/**cookie.getValue取出值*/
                    long time = Long.parseLong(cookie.getValue());
                    Date d = new Date(time);
                    flag = true;
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String formatTime = sdf.format(d);
                    /*打印名是cookie的值*/
                    resp.getWriter().println("上一次你访问的时间是:" + formatTime);
                    break;
                }
            }
        }

        if(false){
            resp.getWriter().println("你是第一次访问我们的网站....谢谢您!");
        }
        /*添加一个cookie*/
        Cookie cookie = new Cookie("lastTime",System.currentTimeMillis() + "");
        /*设置cooki的有效时间,单位秒*/
        cookie.setMaxAge(60);
        /**cookie.setMaxAge(0) 删除cookie,也可以浏览器手动删除*/
        resp.addCookie(cookie);

    }

Session在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
doPost或doGet方法

/*获取session*/
HttpSession session = req.getSession();
/*向session里面写入数据*/
session.setAttribute("userName","王一辉");
/*从session拿出数据*/
String s = (String) session.getAttribute("userName");
/*获得sessionID*/
String sessionID = session.getId();

jsp拿到session里面userName的值

${sessionScop.userName}

区别:
1、数据存放位置不同:
cookie数据存放在客户的浏览器上,session数据放在服务器上。

filter过滤器

xml

  <filter>
    <filter-name>TestFilter1</filter-name>
    <filter-class>com.yingside.filter.TestFilter1</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>TestFilter1</filter-name>
    <url-pattern>/*</url-pattern>

类实现Filter,重写destory(),doFilter(),init()方法

public class TestFilter1 implements Filter {
    public void destroy() {
        System.out.println("----TestFilter1.destroy----");
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        System.out.println("TestFilter1.doFilter1111111");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        System.out.println("======TestFilter1.init======");
    }

}
配置类写法(自动登陆功能)
@WebFilter(filterName = "AutoLoginFilter",urlPatterns = "*.do")
public class AutoLoginFilter implements Filter {
    private UserDao mapper = null;
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse) resp;

        HttpSession session = request.getSession();
        Object u = session.getAttribute("user");
        if(u != null){
            chain.doFilter(req, resp);
            return;
        }

        Cookie[] cookies = request.getCookies();
        String value = null;
        if(cookies != null){
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if(cookie.getName().equals("autoLogin")){
                    value = cookie.getValue();
                    break;
                }
            }


            if(value != null){
                String[] s = value.split("_");
                String username = s[0];
                String password = s[1];
                User user = mapper.login(username,password);
                if(user != null){

                    session.setAttribute("user",user);
                }
            }
        }

        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        String s = "mybatis-config.xml";
        InputStream ins = this.getClass().getClassLoader().getResourceAsStream(s);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(ins);
        SqlSession sqlSession = factory.openSession();
        mapper = sqlSession.getMapper(UserDao.class);
    }

}

Listener监听器

Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,这样就可以给在线人数加1。就可以实现当前在线人数的功能。

监听对象:

1、ServletContext:application,整个应用只存在一个

2、HttpSession:session,针对每一个对话

3、ServletRequest:request,针对每一个客户请求
创建步骤:

1、创建一个实现监听器接口的类

2、配置web.xml文件,注册监听器

<listener>
	<listener-class>完整类名</listener-class>
</listener>

注意:

监听器的启动顺序:按照web.xml的配置顺序来启动

加载顺序:监听器>过滤器>Servlet

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值