当前位置: 首页 > news >正文

互联网轻量级框架整合之JavaEE基础II

编写本篇代码并实际执行之前请仔细阅读前一篇互联网轻量级框架整合之JavaEE基础I

Servlet

在Servlet容器中,Servlet是最基础的组件,也可以把JSP当做Servlet,JSP的存在意义只在于方便编写动态页面,使Java语言能和HTML相互结合,然后在前后端分离大势下,JSP的讨论已经意义不大;按照Servlet3.0以后的规范,组件都可以使用注解来配置,而不必使用web.xml配置,随着Spring Boot的流行,使用注解开发的方式成为主流

首先在pom文件中添加如下依赖

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency>

新建路径src/mian/java/com/ssm/servlet,在该路径下新建java文件,并命名为MyServlet(Java基础关于命名规则此处不解)

package com.ssm.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;// 使用@WebServlet将类标识为Servlet, Servlet容器会自动识别
@WebServlet(name="myServlet",urlPatterns="/my"    //Servlet拦截路径,可以使用正则
)
public class MyServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{response.getWriter().print("Hello Servlet");  //写入返回信息}}

在编译器中直接执行,并访问路径/my,浏览器会展示如下内容
在这里插入图片描述

代码解析

首先代码中使用@WebServlet自定义了一个servlet,并命名为myServlet,该servlet会拦截/my这个路径下的动作,然后定义了一个MySeervlet类它扩展了HttpServlet这个基础类,将其doGet方法重写从而返回Hello Servlet字符串,基础类中的doGet方法源码如下

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_get_not_supported");if (protocol.endsWith("1.1")) {resp.sendError(405, msg);} else {resp.sendError(400, msg);}}

面向对象编程中的重写(override)指的是子类可以重写其父类中的非private方法,使得子类在调用该方法时会使用自己的实现而不是父类的实现
面向对象编程中的重载(Overload)指的是在同一个类中声明多个方法,它们拥有相同的名称,但是参数类型或数量不同

Servlet生命周期

Servlet在Java中是个接口,在它基础上实现了两个抽象类GenerticServlet和HttpServlet,两个抽象类中分别实现了若干方法
在这里插入图片描述

package com.ssm.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;// 使用@WebServlet将类标识为Servlet, Servlet容器会自动识别
@WebServlet(name="myServlet",urlPatterns="/my"    //Servlet拦截路径,可以使用正则
)
public class MyServlet extends HttpServlet {@Overridepublic void init(){System.out.println("init方法调用");}@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{System.out.println("doGet方法调用");response.getWriter().print("Hello Servlet");  //写入返回信息}@Overridepublic void destroy(){System.out.println("destroy方法调用");}}

代码解析

代码中新增了init()方法和destroy()方法,均是重写了原方法,但细看HttpServlet这个基础抽象类中并没有这两个方法的实现,发现HttpServlet是扩展了GenericServlet类,在这个类中实现了init()方法和Destroy()方法
在这里插入图片描述
上边代码在第一次执行的时候,会在控制台输出init方法调用doGet方法调用字样,刷新页面(再次请求)控制台只会输出doGet方法调用,表明在第一次请求时,Servlet容器会构建Servlet实例,然后进行初始化,接着调用服务类方法而响应请求;在第二次请求则是直接调用服务类方法响应请求不会再调用init方法进行初始化Servlet实例的动作,可见这个过程Servlet只有一个实例而并非多个,而该Servlet实例会在Servlet容器正常关闭或者Servlet实例超时的时候执行destroy()方法,从而销毁该Servlet实例

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

Servlet参数配置

package com.ssm.servlet;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;// 使用@WebServlet将类标识为Servlet, Servlet容器会自动识别
@WebServlet(name="myServlet",urlPatterns="/my", //Servlet拦截路径,可以使用正则asyncSupported = true, //是否异步执行默认为false, 表示不使用异步线程运行Servlet,设置为true代表支持多线程异步loadOnStartup = 1, //启动顺序,如果小于或者等于0,则不在项目启动时加载,只会在第一次请求时才会初始化,如果大于0,则在项目启动时加载initParams = { //Servlet参数@WebInitParam(name = "init.param1", value = "init-value1"),@WebInitParam(name = "init.param2", value = "init.value2")}
)
public class MyServlet extends HttpServlet {@Overridepublic void init(ServletConfig servletConfig){System.out.println("init方法调用");String param1 = servletConfig.getInitParameter("init.param1");String param2 = servletConfig.getInitParameter("init.param2");System.out.println(param1);System.out.println(param2);}@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{System.out.println("doGet方法调用");response.getWriter().print("Hello Servlet");  //写入返回信息}@Overridepublic void destroy(){System.out.println("destroy方法调用");}}
01-Apr-2024 14:22:34.934 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina]
01-Apr-2024 14:22:34.934 信息 [main] org.apache.catalina.core.StandardEngine.startInternal 正在启动 Servlet 引擎:[Apache Tomcat/9.0.87]
01-Apr-2024 14:22:34.953 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"]
01-Apr-2024 14:22:34.976 信息 [main] org.apache.catalina.startup.Catalina.start [94]毫秒后服务器启动
Connected to server
[2024-04-01 02:22:35,311] Artifact Chapterone:war: Artifact is being deployed, please wait...
init方法调用
init-value1
init.value2
[2024-04-01 02:22:35,907] Artifact Chapterone:war: Artifact is deployed successfully
[2024-04-01 02:22:35,908] Artifact Chapterone:war: Deploy took 597 milliseconds
01-Apr-2024 14:22:44.999 信息 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [D:\apache-tomcat-9.0.87\webapps\manager]
01-Apr-2024 14:22:45.067 信息 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\apache-tomcat-9.0.87\webapps\manager]的部署已在[67]毫秒内完成

在控制台输出中可以看到,页面并没有请求/my路径的(并未请求定义的servlet)情况下,也输出了配置信息,表明虽为请求但项目启动就已经加载了该servlet

HttpServletRequest

package com.ssm.servlet;import javax.servlet.ServletContext;
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 javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet(name = "reqServlet",urlPatterns = "/request/*"
)public class RequestServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{//获取请求信息int prot = request.getServerPort();String url = request.getRequestURI().toString();String uri = request.getRequestURI();System.out.println("服务器端口:" + prot);System.out.println("url:" + url);System.out.println("uri:" + uri);//获取请求头String userAgent = request.getHeader("User-Agent");System.out.println("User-Agent:" + userAgent);//获取参数String param1 = request.getParameter("param1");String param2 = request.getParameter("param2");//获取上下文ServletContext application = request.getServletContext();//设置上下文属性application.setAttribute("application", "application-value");//设置请求属性request.setAttribute("param1", param1);request.setAttribute("param2", param2);//设置Session属性HttpSession session = request.getSession();// 设置Session超时时间单位ssession.setMaxInactiveInterval(1800);session.setAttribute("session1", "session-value1");//跳转到JSP页面request.getRequestDispatcher("/request-result.jsp") //此时会传递请求和响应的上下文,但浏览器地址不会发生改变.forward(request,response);}}

JSP页面代码,放在src/main/webapp路径下

<%--Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%out.print("<h2>内置对象request</h2>");String param1 = (String) request.getAttribute("param1");String param2 = (String) request.getAttribute("param2");out.print("param1 =>" + param1 + "<br>");out.print("param1 =>" + param2 + "<br>");out.print("<h2>内置对象session</h2>");String sessionValue = (String) session.getAttribute("session1");out.print("session1 =>" + sessionValue + "<br>");out.print("<h2>内置对象application</h2>");String appValue = (String) application.getAttribute("application");out.print("application =>" + appValue + "<br>");
%>
</body>
</html>

在IDEA中执行代码,并使用连接/request/url?param1=value1&param2=value2请求服务
在这里插入图片描述
同时在控制台会输出如下内容

服务器端口:8080
url:/Chapterone_war/request/url
uri:/Chapterone_war/request/url
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36

代码解析

这段代码结合了JSP,涉及到了JSP中3个重要内置对象requestsessionapplication,在使用这些内置对象时非常重要的一个概念便是作用域,比如request请求对象的作用域仅当次用户请求有效;session的作用域是浏览器和服务器会话期间有效,它是服务器在浏览器通信期间为了保存会话数据开辟的内存空间,通过一个sessionId进行关联;application的作用域是Web项目在Servlet容器中存活期间有效;还有一个不常用的内置对象page,其作用域只对当前页面有效,使用率很低; 其他解释见注释即可

HttpServletResponse

HttpServletRequest和HttpServletResponse这两个类是在Servlet开发中最常用的两个类,HttpServletResponse也被称为响应对象,主要用于设置响应头和响应体,在前后端分离的场景下,页面主要通过AJAX(Asynchronous Javascript And XML)获取数据,移动端应用也类似,因此后端更多的响应类型会以JSON数据集为主,这时就需要通过HttpServletResponse设置响应类型和编码

package com.ssm.servlet;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;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson2.JSON;@WebServlet(name= "respServlet",urlPatterns = "/response/*"
)public class RessponseServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException{//获取参数String param1 = request.getParameter("param1");String param2 = request.getParameter("param2");//将参数写到Map数据结构中Map<String, String> resultMap = new HashMap<>();resultMap.put("param1", param1);resultMap.put("param2", param2);//转换为JSON数据集String json = JSON.toJSONString(resultMap);//设置响应信息为JSON类型response.setContentType("application/json");//设置响应信息编码为UTF-8response.setCharacterEncoding("UTF-8");//设置响应头response.setHeader("success", "true");//设置状态码response.setStatus(200);//获取输出对象PrintWriter out = response.getWriter();//输出信息out.println(json);}}

执行代码并访问链接/response/my?param1=value1&param2=value2
在这里插入图片描述
在这里插入图片描述

HttpServletResponse进行跳转

package com.ssm.servlet;import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(name= "respJSP",urlPatterns = "/resp/jsp/*"
)public class RessponseJspServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException{//获取参数String param1 = request.getParameter("param1");String param2 = request.getParameter("param2");String param3 = request.getParameter("param3");request.setAttribute("param1", param1);request.getSession().setAttribute("param2", param2);request.getServletContext().setAttribute("param3", param3);response.sendRedirect("/Chapterone_war/response-result.jsp"); //这里的跳转需要使用全路径}}
<%--Created by IntelliJ IDEA.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%out.print("<h2>内置对象request</h2>");String param1 = (String) request.getAttribute("param1");out.print("param1=>" + param1 + "<br>");out.print("<h2>内置对象session</h2>");String param2 = (String) session.getAttribute("param2");out.print("param2=>" + param2 + "<br>");out.print("<h2>内置对象application</h2>");String param3 = (String) application.getAttribute("param3");out.print("param3=>" + param3 + "<br>");%>
</body>
</html>

重新执行并访问页面/resp/jsp/my?param1=value1&param2=value2&param3=value3如下结果
在这里插入图片描述

可以看到param1的值为null,也就是并没有获取到,因为HttpServletResponse的跳转并不传递请求上下文,所以不能读取Servlet中HttpServletRequest设置的属性,只能查看Session的属性和ServletContext的属性

过滤器

过滤器Filter其作用是在Servlet执行的过程前后执行一些逻辑,例如可以控制对Servlet的访问权限,在Servlet规范中,需要使用注解@WebFilter标识过滤器,同时需要实现Filter接口,该接口代码如下

package javax.servlet;import java.io.IOException;public interface Filter {//初始化方法,在项目启动时先于Servlet的init方法执行default void init(FilterConfig filterConfig) throws ServletException {}//过滤逻辑,filterChain参数是放行标准void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;//过滤器超时或者Servlet容器正常关闭时候会调用,且是在Servlet的destroy方法之后执行default void destroy() {}
}
package com.ssm.servlet;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebFilter(filterName = "servletFilter",//请求拦截的范围urlPatterns = {"/request/*", "/response/*"},//需要拦截的Servlet,需要提供Servlet名称servletNames = {"reqServlet", "respServlet"},//初始化参数initParams = {@WebInitParam(name="init_param1", value = "init-value-1"),@WebInitParam(name="init_param2", value = "init-value-2")}
)public class ServletFilter implements Filter {//初始化@Overridepublic void init(FilterConfig filterConfig) throws ServletException{String initParam1 = filterConfig.getInitParameter("init_para1");String initParam2 = filterConfig.getInitParameter("init_para2");System.out.println("Filter初始化参数:param1=>" + initParam1);System.out.println("Filter初始化参数:param2=>" + initParam2);}/**** @param req 请求对象* @param resp 响应对象* @param filterChain 过滤器责任链* @throws IOException* @throws ServletException*/@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException{//强制转换HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;request.setCharacterEncoding("UTF-8");//获取参数String param1 = request.getParameter("param1");if(param1 == null || param1.trim().equals("")){response.setCharacterEncoding("UTF-8");response.setContentType("text/html");response.getWriter().println("没有参数:param1, 拦截请求");//在过滤器中结束请求,不再转发到Servletreturn;}filterChain.doFilter(req,resp);}@Overridepublic void destroy(){System.out.println("Filter销毁方法");}
}
  • 过滤器中doFilter是核心,在此代码中首先从请求中获取参数param1,如果为空,则拦截请求并提示信息,并返回,如果不为空则执行filterChain.doFilter(req, resp);放行该请求

在编译器中关闭Tomcat服务,如图所示可以看到过滤器的init()、destroy()方法和其他servlet中相关方法的执行顺序
在这里插入图片描述

监听器

在Servlet的规范中存在多种监听,例如监听Servlet上下文属性的ServletContextAttributeListener、监听请求的ServletRequestListener和监听Session属性操作的HttpSessionAttributeListener等

package com.ssm.servlet;import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;@WebListener
public class WebContextListener implements ServletContextListener {/*** Servlet上下文初始化后的逻辑* @param sce*/public void contextInitialized(ServletContextEvent sce)  {System.out.println("Servlet上下文初始化后的逻辑");}/*** Servlet上下文销毁后的逻辑* @param sce*/public void contextDestroyed(ServletContextEvent sce)  {System.out.println("Servlet上下文销毁后的逻辑");// 关闭数据库连接池}
}

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

启动项目可以看到contextInitialized方法在过滤器的init方法之前执行,正常关闭Servlet容器,则ContextDestroyed方法在过滤器的destroy方法之后执行

Servlet容器初始化器

Servlet容器初始化器ServletContainerInitializer允许将一些第三方的类加载到Servlet容器中,加载哪些类通过注解@HandlesTypes来指定

package com.ssm.servlet;public interface OuterService {void sayHello(String servlet容器初始化器);
}
package com.ssm.servlet;public class OuterServiceImpl implements OuterService{@Overridepublic void sayHello(String ss) {// TODO 自动生成的方法存根System.out.println(ss);}
}
package com.ssm.servlet;import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import java.lang.reflect.Constructor;
import java.util.Objects;
import java.util.Set;//配置需要加载的类,连同类的实现或者子类加载进来
@HandlesTypes(value = {OuterService.class})
public class WebContainInitializer implements ServletContainerInitializer {/**** @param set 加载类集合* @param servletContext Servlet上下文* @throws ServletException*/@Overridepublic void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {for(Class clazz:set){try {Class[] itfs = clazz.getInterfaces();for(Class itf:itfs){if(OuterService.class.equals(itf)){ //符合当前配置的类//获取构造方法数组Constructor<?>[] constructors = Class.forName(clazz.getName()).getConstructors();//通过反射创建对象Object service = constructors[0].newInstance();//强制转换OuterService outerService = (OuterService) service;//执行服务方法outerService.sayHello("Servlet容器初始化器");//将服务对象放入上下文servletContext.setAttribute("outerService",outerService);break;}}}catch (Exception e){e.printStackTrace();}}}
}

Servlet初始化器标注了@HandlesTypes,并且指定了加载类型为OuterService,同时初始化器实现了ServletContainerInitializer的onStartup方法,该方法会在Servlet上下文构建时执行,它有两个参数,set是一个@HandlesTypes所指定类型的集合,该集合包含所指定类型的实现类或子类,另一个是servletContext,它是Servlet的上下文

然后在项目结构中如图所示新建文件及内容
在这里插入图片描述
文件名 javax.servlet.ServletContainerInitializer文件内容javax.servlet.ServletContainerInitializer, 实际上就是指向刚才写好的初始化类,然后启动项目
在这里插入图片描述
在所有监听器、过滤器和Servlet初始化之前,控制台输出Servlet容器初始化器

使用Cookie

package com.ssm.servlet;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 javax.servlet.http.Cookie;@WebServlet(name = "cookieServlet",urlPatterns = "/cookie/*"
)
public class CookieServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{response.setContentType("text/html");response.setCharacterEncoding("UTF-8");String action = request.getParameter("action");if("write".equalsIgnoreCase(action)){//写入cookieresponse.getWriter().println("<h1>写入cookie</h1>");this.writeCookie(request, response);}else if("show".equalsIgnoreCase(action)){//显示cookiethis.showCookie(request, response);}else{response.getWriter().println("<h1>404</h1>");}}private void writeCookie(HttpServletRequest request, HttpServletResponse response) throws IOException{for(int i=1; i<10; i++){Cookie cookie = new Cookie("cookie"+i, "cookie"+i);response.addCookie(cookie);}response.getWriter().println("<h1>写入cookie成功</h1>");}private void showCookie(HttpServletRequest request, HttpServletResponse response) throws IOException{Cookie[] cookies = request.getCookies();if(cookies != null){for(Cookie cookie : cookies){response.getWriter().println("<h1>"+cookie.getName()+"</h1>");response.getWriter().println("<h1>"+cookie.getValue()+"</h1>");}}else {response.getWriter().println("<h1>没有cookie</h1>");}}
}

在这里插入图片描述

提交表单

<%--Created by IntelliJ IDEA.User: AdministratorDate: 2024/4/1Time: 20:46To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Test Post Request</title>
</head>
<body>
<form action="./postServlet" method="post">角色名称:<input id="role_id" type="text" name="roleName"><br>角色描述:<input id="desc_id" type="text" name="roleDesc"><br><input type="submit" value="提交">
</form>
</body>
</html>
package com.ssm.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet(name="postServlet",urlPatterns = "/postServlet"
)public class PostServlet extends HttpServlet {@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String roleName = request.getParameter("roleName"); //input标签里的name值 不是idString desc = request.getParameter("roleDesc");//input标签里的name值 不是idresponse.setContentType("text/html");response.setCharacterEncoding("UTF-8");PrintWriter out = response.getWriter();out.println("提交的表单参数【roleName】为:"+roleName);out.println("提交的表单参数【desc】为:"+desc);}
}

使用web.xml

除了使用Servlet.3.0规范给出的各种注解之外,还可以使用web.xml配置Servlet、监听器和过滤器等的内容,将之前写的代码里的注解标识全部去掉,这样Servlet容器就无法识别它了,然后再在web.xml里配置一遍
在这里插入图片描述

类似如下方式(猴烦猴烦的)

<?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"><!--配置监听--><listener><listener-class>com.ssm.servlet.WebContextListener</listener-class></listener><!--配置过滤器--><filter><!--过滤器名称--><filter-name>servletFilter</filter-name><filter-class>com.ssm.servlet.ServletFilter</filter-class><init-param><param-name>init_param1</param-name><param-value>init-value-1</param-value></init-param><init-param><param-name>init_param2</param-name><param-value>init-value-2</param-value></init-param></filter><filter-mapping><filter-name>servletFilter</filter-name><url-pattern>/response/*,/request/*</url-pattern></filter-mapping><servlet><servlet-name>myServlet</servlet-name><servlet-class>com.ssm.servlet.MyServlet</servlet-class><init-param><param-name>init.param1</param-name><param-value>init-value-1</param-value></init-param><init-param><param-name>init.param2</param-name><param-value>init-value-2</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>myServlet</servlet-name><url-pattern>/my</url-pattern></servlet-mapping><servlet><servlet-name>CookieServlet</servlet-name><servlet-class>com.ssm.servlet.CookieServlet</servlet-class><init-param><param-name>init.param1</param-name><param-value>init-value-1</param-value></init-param><init-param><param-name>init.param2</param-name><param-value>init-value-2</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>CookieServlet</servlet-name><url-pattern>/cookie/*</url-pattern></servlet-mapping><session-config><session-timeout>30</session-timeout></session-config><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><error-page><error-code>404</error-code><location>/WEB-INF/jsp/404.jsp</location></error-page><error-page><error-code>500</error-code><location>/WEB-INF/jsp/500.jsp</location></error-page></web-app>

相关文章:

  • 设计模式学习笔记 - 设计模式与范式 -结构型:4.适配器模式
  • 力扣刷题Days30-238. 除自身以外数组的乘积(js)
  • 软考中级(网络工程师考核要点)第一章 计算机网络系统(信道特性应用)第五期(曼彻斯特和差分曼彻斯特)重点考
  • 浅析MNN
  • Linux权限提升总结
  • 《新机器智能》的深度解读与感悟
  • Python版【植物大战僵尸 +源码】
  • Python爬虫:爬虫常用伪装手段
  • linux安装多个版本的java
  • 6、【单例模式】确保了一个类在程序运行期间只有一个实例
  • Python爬虫如何快速入门
  • 计算机网络中---基本概念
  • NRF52832修改OTA升级时的bootloader蓝牙MAC
  • 医疗器械测试面试准备—质量部总监二面
  • 封装Redis工具类
  • Golang-长连接-状态推送
  • Java多线程(4):使用线程池执行定时任务
  • js ES6 求数组的交集,并集,还有差集
  • Linux中的硬链接与软链接
  • Odoo domain写法及运用
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • React组件设计模式(一)
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 程序员最讨厌的9句话,你可有补充?
  • 和 || 运算
  • 技术:超级实用的电脑小技巧
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 排序算法学习笔记
  • 前端性能优化--懒加载和预加载
  • 双管齐下,VMware的容器新战略
  • 算法系列——算法入门之递归分而治之思想的实现
  • 正则与JS中的正则
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #define、const、typedef的差别
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (16)Reactor的测试——响应式Spring的道法术器
  • (ZT)出版业改革:该死的死,该生的生
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (四)c52学习之旅-流水LED灯
  • (四)linux文件内容查看
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)JAVA中的堆栈
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .NET 回调、接口回调、 委托
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .Net程序帮助文档制作
  • .net中应用SQL缓存(实例使用)
  • .php文件都打不开,打不开php文件怎么办
  • .skip() 和 .only() 的使用
  • @RequestBody详解:用于获取请求体中的Json格式参数