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

news2024/11/28 16:43:59

编写本篇代码并实际执行之前请仔细阅读前一篇互联网轻量级框架整合之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 {
    @Override
    public 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 {

    @Override
    public void init(){
        System.out.println("init方法调用");
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
        System.out.println("doGet方法调用");
        response.getWriter().print("Hello Servlet");  //写入返回信息
    }

    @Override
    public 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 {

    @Override
    public 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);
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
        System.out.println("doGet方法调用");
        response.getWriter().print("Hello Servlet");  //写入返回信息
    }

    @Override
    public 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 {

    @Override
    public 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超时时间单位s
        session.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 {

    @Override
    public 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-8
        response.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 {

    @Override
    public 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 {
    //初始化
    @Override
    public 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
     */
    @Override
    public 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, 拦截请求");
            //在过滤器中结束请求,不再转发到Servlet
            return;
        }
        filterChain.doFilter(req,resp);
    }

    @Override
    public 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{
    @Override
    public 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
     */
    @Override
    public 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)){
            //写入cookie
            response.getWriter().println("<h1>写入cookie</h1>");
            this.writeCookie(request, response);
        }else if("show".equalsIgnoreCase(action)){
            //显示cookie
            this.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: Administrator
  Date: 2024/4/1
  Time: 20:46
  To 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 {
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String roleName = request.getParameter("roleName"); //input标签里的name值 不是id
        String desc = request.getParameter("roleDesc");//input标签里的name值 不是id
        response.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.coloradmin.cn/o/1562435.html

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

相关文章

深度学习-计算机视觉入门-part1

计算机视觉入门 文章目录 计算机视觉入门一、 从卷积到卷积神经网络1.图像的基本表示2. 卷积操作3.卷积遇见深度学习3.1 通过学习寻找卷积核3.2 参数共享&#xff1a;卷积带来参数量骤减3.3 稀疏交互&#xff1a;获取更深入的特征 二、手撕卷积代码三、经典CNN模型介绍四、CNN模…

爬取BOSS直聘招聘数据(详情页数据+__zp_stoken__逆向)

这里携带逆向方法进行请求 获得数据 需要逆向方法请私聊 , 下面部分只展示爬取思路 对网页进行分析抓包 设置参数 – 城市/薪资范围/职业 对网页进行请求获得数据集 利用xpath,soup等进行进行数据清洗 将数据一csv的格式保存

【面试八股总结】超文本传输协议HTTP(一)

一、 什么是HTTP协议&#xff1f; HTTP是超文本传输协议 HyperText Transfer Protocol 特性&#xff1a; 简单、灵活、易于扩展无状态&#xff1a;服务器不会记忆HTTP状态不安全&#xff1a;通信使用明文&#xff0c;不验证通信方身份&#xff0c;无法的证明报文的完整性&…

研发设计人员能力级别定义

研发设计人员能力&级别定义 1. 源由2. 级别定义3. 级别能力3.1 助理工程师3.1.1 工作内容3.1.2 级别晋升3.1.3 详细描述 3.2 初级工程师3.2.1 工作内容3.2.2 级别晋升3.2.3 详细描述 3.3 高级工程师3.3.1 工作内容3.3.2 级别晋升3.3.3 详细描述 3.4 资深工程师3.4.1 工作内…

百度网站收录提交入口

百度网站收录提交入口 在网站刚建立或者更新内容后&#xff0c;及时将网站提交给搜索引擎是提高网站曝光和获取流量的重要步骤之一。百度作为中国最大的搜索引擎之一&#xff0c;网站在百度中的收录情况尤为重要。下面介绍一下如何通过百度的网站收录提交入口提交网站。 1. 百…

黑马HTMLCSS基础

黑马的笔记和资料都是提供好了的&#xff0c;这个文档非常适合回顾复习。我在黑马提供的笔记上做了一些微不足道的补充&#xff0c;以便自己复习查阅。该笔记比较重要的部分是 表单&#xff0c;http请求 第一章. HTML 与 CSS HTML 是什么&#xff1a;即 HyperText Markup lan…

VScode 集成终端设置默认打开当前文件夹 mac系统

一.快捷键设置 搜索 openInIntegratedTerminal 如图&#xff1a; 二.设置cmd 默认打开位置 点击设置 搜索 ntegrated:cwd 如下图&#xff1a; 三.查看ip 快捷指令&#xff1a; ipconfig getifaddr en0

【御控物联】JSON结构数据转换在物联业务中应用(场景案例二)

文章目录 一、物联网业务场景现状二、物联网业务场景数据交互格式三、JSON格式数据转换案例四、JSON数据格式转换DEMO五、在线转换工具六、技术资料 一、物联网业务场景现状 目前&#xff0c;市场上多数物联网关与物联平台捆绑售卖&#xff0c;网关采集到设备数据只能按照指定…

亲测可用,解决matplotlib中文字体乱码问题(使用Windows设置)

SimHei字体下载 https://pan.baidu.com/s/14BzhntzSeEjE4FmlVENwUw?pwd1111 用我自己的,看了好几个其他博主的帖子,所用的下载链接都失效了,太TM不靠谱了 import matplotlib.pyplot as plt import random x range(60) x_ticks_label ["11点{}分".format(i) for …

HashMap 集合源码分析

系列文章目录 文章目录 系列文章目录前言谈一谈HashMap的红黑树节点类 TreeNode 设计一、字段分析二、构造方法分析三、内部类分析四、方法分析五、扩容分析六、总结 前言 HashMap 底层是使用了 哈希表&#xff08;数组实现的哈希表&#xff09; 链表 红黑树 实现的&#xff…

Spring框架之WebFlux

Spring WebFlux高级实战 1、WebFlux作为核心响应式服务器基础 Spring 框架的整个基础设施都是围绕Servlet API 构建的&#xff0c;它们之间紧密耦合。 因此在开始深入响应式Web 之前&#xff0c;先回顾一下Web 模块的设计&#xff0c;看看它做了什么。 底层Servlet 容器负责…

mysql 数据库的MHA高可用

目录 一、MHA概述&#xff1a; 1.认识MHA&#xff1a; 2.MHA 的组成&#xff1a; 3.MHA 的特点&#xff1a; 4.MHA 工作原理&#xff1a; 5.数据流向&#xff1a; 6.数据同步方式&#xff1a; 7. mysql 的高可用 &#xff1a; 二. MySQL MHA 的搭建: 1. 修改 Master、…

LeetCode刷题:无重复字符的最长子串 详解 【3/1000 第三题】

&#x1f464;作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 LeetCode解锁1000题: 打怪升级之旅htt…

单片机简介(一)

51单片机 一台能够运行的计算机需要CPU做运算和控制&#xff0c;RAM做数据存储&#xff0c;ROM做程序存储&#xff0c;还有输入/输出设备&#xff08;串行口、并行输出口等&#xff09;&#xff0c;这些被分为若干块芯片&#xff0c;安装在主板&#xff08;印刷线路板&#xf…

文本直接生成2分钟视频,即将开源模型StreamingT2V

Picsart人工智能研究所、德克萨斯大学和SHI实验室的研究人员联合推出了StreamingT2V视频模型。通过文本就能直接生成2分钟、1分钟等不同时间&#xff0c;动作一致、连贯、没有卡顿的高质量视频。 虽然StreamingT2V在视频质量、多元化等还无法与Sora媲美&#xff0c;但在高速运…

记一次 pdfplumber 内存泄漏导致的服务器宕机

有一个项目需求&#xff0c;要在每天凌晨5点的时候执行一个任务&#xff0c;获取一系列的PDF文件并解析。 后端是Django框架&#xff0c;定时任务用Celery来实现的。 本地跑没什么问题&#xff0c;但是一放到服务器上跑就会宕机&#xff0c;而且是毫无征兆的宕机&#xff0c;…

css- 4

1.浮动 1. 浮动最初用于实现文字环绕效果 2. 现在&#xff0c;浮动是主流的布局方式之一 1.1元素浮动之后的特点 元素浮动之后&#xff0c;称为浮动元素&#xff0c;具有如下特点&#xff1a; 1. 浮动元素脱离文档流 2. 多个浮动的元素会水平排列&#xff0c;一行放不下自动换…

【STM32嵌入式系统设计与开发】——14PWM(pwm脉宽输入应用)

这里写目录标题 一、任务描述二、任务实施1、WWDG工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#xff08;2&#xff09;USART1初始化函数(usart1_init())&#xff08;3&#xff09;USART数据发送函数&#xff08; USART1_Send_Data&#xff08;&#xff09…

浅聊什么是Redis?

需求&#xff1a;MySQL面临大量的查询&#xff0c;即读写操作&#xff0c;因此类比CPU&#xff0c;给数据加缓存&#xff0c;Redis诞生。应用程序从MySQL查询的数据&#xff0c;在Redis设置缓存&#xff08;记录在内存中&#xff0c;无需IO操作&#xff09;&#xff0c;后再需要…

记录Xshell使用ed25519公钥免密链接SSH

试了半天&#xff0c;Xshell好像没办法导入linux生成的ssh公钥,因此需要以下步骤实现免密登录 结论&#xff0c;在linux公钥文件中&#xff0c;将客户端生成的ed25519公钥加上去即可(一个公钥单独一行) 1.使用Linux生成秘钥文件(不需要输入私钥密码passphrase)或者直接创建一…