互联网轻量级框架整合之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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/793844.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

产品推荐 | 中科亿海微推出亿迅®A8000金融FPGA加速卡

01、产品概述 亿迅A8000金融加速卡&#xff0c;是中科亿海微联合金融证券领域的战略合作伙伴北京睿智融科&#xff0c;将可编程逻辑芯片与金融行业深度结合&#xff0c;通过可编程逻辑芯片对交易行情加速解码&#xff0c;实现低至纳秒级的解码引擎&#xff0c;端到端的处理时延…

Linux gcc day3

find命令&#xff08;importance&#xff09;&#xff1a; 语法&#xff1a;find pathname -options find /root -name test.c which命令&#xff1a; which [指令] 只搜索指令&#xff0c;在什么位置下 为什么文件夹带有颜色呢&#xff1f; 科普补充alias命令&#xff1a; ali…

C++:赋值运算符(17)

赋值也就是将后面的值赋值给变量&#xff0c;这里最常用的就是 &#xff0c;a1那么a就是1&#xff0c;此外还包含以下的赋值运算 等于int a 1; a10 a10加等于int a 1; a1;a2-减等于int a 1; a-1;a0*乘等于int a 2; a*5;a10/除等于int a 10; a/2;a5%模等于int a 10; a%…

kafka集群介绍+部署Filebeat+Kafka+ELK

一、消息队列 1、为什么需要消息队列&#xff08;MQ&#xff09; 主要原因是由于在高并发环境下&#xff0c;同步请求来不及处理&#xff0c;请求往往会发生阻塞。比如大量的请求并发访问数据库&#xff0c;导致行锁表锁&#xff0c;最后请求线程会堆积过多&#xff0c;从而触…

Mac电脑清理垃圾软件 Mac电脑清理垃圾的文件在哪 cleanMyMac X 4.8.0激活号码

Mac用户经常会有这样一些烦恼&#xff0c;比如软件之间的管理&#xff0c;应用生成的缓冲文件怎样删除&#xff0c;还有软件的卸载等等... 如何有效清理Mac中的垃圾文件&#xff0c;删除多余的软件成为Mac用户迫切的需求。本文就为大家介绍几款好用的Mac电脑清理垃圾软件&#…

在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)

在线考试管理系统目录 目录 基于Springboot的在线考试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台&#xff1a; 2、后台 管理员功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主…

Redis中的Sentinel(二)

Sentinel 初始化Sentinel状态。 在应用了Sentinel的专用代码之后&#xff0c;接下来&#xff0c;服务器会初始化一个sentinel.c/sentinelState结构(简称Sentinel状态),这个结构 保存了服务器中所有和Sentinel功能有关的状态(服务器的一般状态仍然由redis.h/redisServer保存);…

SaaS 电商设计 (十) 记一次 5000kw 商品数据ES迁移 (详细的集群搭建以及线上灰度过程设计)

目录 一.背景二.技术目标三.技术方案3.1 整体流程3.2 ES 切换前:完成整体新集群的搭建.i:拓扑结构设计ii: 如何选择整体的 **ES** 集群配置. 3.3 **ES** 版本切换中3.3.1 多client版本兼容3.3.2 Router的设计 3.4 ES 切换后3.5 开箱即用3.5.1 开箱使用 demo 演示3.5.2 使用过程…

团体程序设计天梯赛-练习集 01

天梯赛题解合集 团体程序设计天梯赛-练习集 (L1-001 - L1-012) 团体程序设计天梯赛-练习集 (L1-013 - L1-024) 团体程序设计天梯赛-练习集 (L1-025 - L1-036) 团体程序设计天梯赛-练习集 (L1-037 - L1-048) L1-001 Hello World 输出题 样例 输入 输出 Hello World!思…

图像处理ASIC设计方法 笔记13 图像旋转ASIC的输入输出电路

文章目录 1 DPRAM:双端口 RAM2 IDT Integrated Device Technology, Inc. 公司介绍3 IDT70T633S10DDI4 TMS320C64145 旋转ASIC的输入输出框图图像旋转ASIC的输入输出电路案例用到的芯片相关介绍如下。 1 DPRAM:双端口 RAM DPRAM 的特点是可以通过两个端口同时访问,具有两套完全…

数据结构入门系列-栈的结构及栈的实现

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 栈 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一段进行插入和删除元素操作&#xff0c;进行数据输入和删除操作的一端称为栈顶&#xff0c;另…

InternLM2-Chat-1.8B 模型测试

在interStudio进行InternLM2-Chat-1.8B模型访问&#xff0c;进入开发机后 配置基础环境 新建conda环境并且进入 conda create -n demo python3.10 -y conda activate demo 下载pytorch等相关包 conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda11.…

ChernoCPP 2

视频链接&#xff1a;【62】【Cherno C】【中字】C的线程_哔哩哔哩_bilibili 参考文章&#xff1a;TheChernoCppTutorial_the cherno-CSDN博客 Cherno的C教学视频笔记&#xff08;已完结&#xff09; - 知乎 (zhihu.com) C 的线程 #include<iostream> #include<th…

四、MySQL读写分离之MyCAT

一、读写分离概述 1、什么是读写分离&#xff1a; 读写分离&#xff1a;就是将读写操作分发到不同的服务器&#xff0c;读操作分发到对应的服务器 &#xff08;slave&#xff09;&#xff0c;写操作分发到对应的服务器&#xff08;master&#xff09; ① M-S (主从) 架构下&…

Java设计模式:外观模式之优雅门面(九)

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在软件工程中&#xff0c;设计模式是解决常见设计问题的经验总结&#xff0c;它为开发者提供了一种通用的、可复用的解决方案。外…

书生浦语训练营2期-第二节课笔记作业

目录 一、前置准备 1.1 电脑操作系统&#xff1a;windows 11 1.2 前置服务安装&#xff08;避免访问127.0.0.1被拒绝&#xff09; 1.2.1 iis安装并重启 1.2.2 openssh安装 1.2.3 openssh服务更改为自动模式 1.2.4 书生浦语平台 ssh配置 1.3 补充&#xff08;前置服务ok…

Thread的基本用法

目录 正文&#xff1a; 1.线程创建 2.线程休眠 3.获取线程实例 4.线程中断 5.线程等待join() 总结&#xff1a; 正文&#xff1a; 1.线程创建 线程创建是多线程编程的第一步&#xff0c;它涉及到创建一个可以并行执行的新线程。在Java中&#xff0c;有几种不同的方法可…

【Laravel】08 RESTful风格

【Laravel】08 视图模板动态渲染数据 1. RESTful风格 1. RESTful风格 (base) ➜ example-app php artisan make:model Blog -mc Model created successfully. Created Migration: 2024_04_01_143040_create_blogs_table Controller created successfully.(base) ➜ example-…

简述JMeter实现分布式并发及操作

为什么要分布式并发&#xff1f; JMeter性能实践过程中&#xff0c;一旦进行高并发操作时就会出现以下尴尬场景&#xff0c;JMeter客户端卡死、请求错误或是超时等&#xff0c;导致很难得出准确的性能测试结论。 目前知道的有两个方法可以解决JMeter支撑高并发&#xff1a; …

阿里 对象存储OSS 云存储服务

1.简介 对象存储服务(Object Storage Service ,OSS) 是一种 海量、安全、低成本、高可靠的云存储服务&#xff0c;适合存放任意类型的文件。容量和处理能力弹性扩展&#xff0c;多种存储类型供选择&#xff0c;全面优化存储成本。 2.如何使用。参考文档 看文档&#xff0c;说的…