Servlet/过滤器/拦截器/监听器:

简介: Servlet接口在Sun公司有两个默认的实现类:HttpServlet、GenericServlet。Servlet是一种运行服务器端的Java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层。

Servlet/过滤器/拦截器/监听器:

1.概述:

1.1 服务程序 Servlet:

Servlet 是 Sun公司在开发动态Web的一门技术,Sun在API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序(把实现了Servlet接口的Java程序叫做:Servlet),只需要完成两个小步骤:

  1. 编写一个类,实现Servlet接口
  2. 把开发好的Java类部署到Web服务器中

Servlet接口在Sun公司有两个默认的实现类:HttpServlet、GenericServlet。Servlet是一种运行服务器端的Java应用程序,具有独立于平台和协议的特性,并且可以动态的生成web页面,它工作在客户端请求与服务器响应的中间层。

1.2 过滤器 Filter:

filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。

1.3 拦截器 Interceptor:

在面向切面编程中,就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法,比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

1.4 监听器 Listener:

监听器,从字面上可以看出listener主要用来监听应用。通过listener可以监听web服务器中某一个执行动作,并根据其要求作出相应的响应。通俗的语言说就是在application,session,request三个对象创建消亡或者往其中添加修改删除属性时自动执 行代码的功能组件。

2.生命周期:

2.1 Servlet 生命周期:

Servlet的生命周期始于它被装入web服务器的内存时,并在web服务器终止或重新装入servlet时结束。servlet一旦被装入web服务器,一般不会从web服务器内存中删除,直至web服务器关闭或重新结束。

  • 装入:启动服务器时加载Servlet的实例;
  • 初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作有init()方法负责执行完成;
  • 调用:从第一次到以后的多次访问,都是只调用doGet()或doPost()方法;
  • 销毁:停止服务器时调用destroy()方法,销毁实例。

2.2 Filter 生命周期:

(一定要实现javax.servlet包的Filter接口的三个方法init()doFilter()destroy(),空实现也行)

  • 启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;
  • 每一次请求时都只调用方法doFilter()进行处理;
  • 停止服务器时调用destroy()方法,销毁实例。

2.3 Listener 生命周期:

Listener 类似于 servlet 和 filter,web.xml 的加载顺序是:context- param -> listener -> filter -> servlet

2.4 Interceptor 生命周期:

以struts的拦截器为例,加载了struts.xml以后,初始化相应拦截器。当action请求来时调用intercept方法,服务器停止销毁interceptor。


3.Servlet 工程:

  • 步骤一:编写一个Servlet程序,编写一个普通类。实现Servlet接口,这里我们直接继承HttpServlet实现类
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
    //由于get或者post只是请求实现的不同方式,可以相互调用,业务逻辑一样;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter(); //获取响应输出流
        writer.println("Hello,Servlet!!!");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  • 步骤二:编写Servlet映射

为什么需要映射?我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接Web服务器,所以我们需要在Web服务中注册我们写的Servlet,还需要给他一个浏览器访问的路径。

<!--注册Servlet-->
<servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>com.krian.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet请求路径-->
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>
  • 步骤三:配置Tomcat服务器

注意部署时细节:


4.Servlet 原理:

Servlet是由Web服务器调用,Web服务器在收到浏览器请求之后,处理请求,返回处理结果!!!

Servlet 中主要的接口:

Servlet接口定义了Servlet与servlet容器之间的契约。这个契约是:Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。但是要注意的是,在一个应用程序中,每种Servlet类型只能有一个实例。

   用户请求致使Servlet容器调用Servlet的Service()方法,并传入一个ServletRequest对象和一个ServletResponse对象。ServletRequest对象和ServletResponse对象都是由Servlet容器(例如TomCat)封装好的,并不需要程序员去实现,程序员可以直接使用这两个对象。

   ServletRequest中封装了当前的Http请求,因此,开发人员不必解析和操作原始的Http数据。ServletResponse表示当前用户的Http响应,程序员只需直接操作ServletResponse对象就能把响应轻松的发回给用户。

   对于每一个应用程序,Servlet容器还会创建一个ServletContext对象。这个对象中封装了上下文(应用程序)的环境详情。每个应用程序只有一个ServletContext。每个Servlet对象也都有一个封装Servlet配置的ServletConfig对象。


Mapping映射问题:

1.一个Servlet可以指定一个映射路径:

<!--Servlet请求路径-->
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>

2.一个Servlet可以指定多个映射路径:

请求的是同一个资源,映射了不同的请求路径!!!

<!--Servlet请求路径-->
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello3</url-pattern>
</servlet-mapping>

3.一个Servlet可以指定通用映射路径:

<!--Servlet通用请求-->
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>hello/*</url-pattern>
</servlet-mapping>

4.指定一些后缀或者前缀等......

<!--自定义后缀实现请求映射-->
<!--注意,*前面不能加项目映射的路径(/)-->
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>*.do</url-pattern>
</servlet-mapping>

5.默认请求路径:

<!--默认请求路径-->
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

6.优先级问题:

指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求。

package com.krian.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 12:35
 * @Tip: Keeping the eyes of the prize !
 * @Description: Error类
 */
@SuppressWarnings({"all"})
public class ErrorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.println("<h1>404,糟糕,页面跑丢了!!!</h1>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<!--注册Servlet-->
<servlet>
  <servlet-name>error</servlet-name>
  <servlet-class>com.krian.servlet.ErrorServlet</servlet-class>
</servlet>
<!--Servlet请求路径-->
<servlet-mapping>
  <servlet-name>error</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

ServletContext对象:

Web容器在启动时,他会为每一个Web程序都创建一个对应的ServletContext对象,他代表当前的Web应用。

1.共享数据:

在一个Servlet中保存的数据,可以在另外一个Servlet中拿到:

package com.krian.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 14:24
 * @Tip: Keeping the eyes of the prize !
 * @Description:
 */
@SuppressWarnings({"all"})
public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletContext可以存放一些数据!!!
        //this.getServletContext():获取Servlet上下文
        ServletContext servletContext = this.getServletContext();
        //处理响应以及网页编码:
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        String userName = "krian";
        //将一个数据保存在ServletContext中,使用键值对的形式:
        servletContext.setAttribute("userName",userName);
    }
}
package com.krian.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 14:31
 * @Tip: Keeping the eyes of the prize !
 * @Description:
 */
@SuppressWarnings({"all"})
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String userName = (String) servletContext.getAttribute("userName");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.println("<h1> 姓名:" + userName + "</h1>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

注册Servlet,在web.xml中配置Servlet:

<?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>
        <servlet-name>contextServlet</servlet-name>
        <servlet-class>com.krian.Servlet.ContextServlet</servlet-class>
    </servlet>
    <!--映射Servlet-->
    <servlet-mapping>
        <servlet-name>contextServlet</servlet-name>
        <url-pattern>/context</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>getServlet</servlet-name>
        <servlet-class>com.krian.Servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getServlet</servlet-name>
        <url-pattern>/get</url-pattern>
    </servlet-mapping>
</web-app>

2.获取初始化参数:

<!--配置web初始化参数-->
<context-param>
  <param-name>url</param-name>
  <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
package com.krian.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 14:48
 * @Tip: Keeping the eyes of the prize !
 * @Description:
 */
@SuppressWarnings({"all"})
public class ParamServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应配置:
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");
        ServletContext servletContext = this.getServletContext();
        String url = servletContext.getInitParameter("url");
        resp.getWriter().println("url:" + url);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
<servlet>
  <servlet-name>paramServlet</servlet-name>
  <servlet-class>com.krian.Servlet.ParamServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>paramServlet</servlet-name>
  <url-pattern>/param</url-pattern>
</servlet-mapping>

3.请求转发:

package com.krian.Servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 14:59
 * @Tip: Keeping the eyes of the prize !
 * @Description: 请求转发!!!
 */
@SuppressWarnings({"all"})
public class DispatcherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //equestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/param"); //请求转发路径
        //requestDispatcher.forward(req,resp); //调用forward实现请求转发
        servletContext.getRequestDispatcher("/param").forward(req,resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>com.krian.Servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/dispatcher</url-pattern>
</servlet-mapping>

4.读取资源文件:

资源导出配置:

<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>false</filtering>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>false</filtering>
    </resource>
  </resources>
</build>

HttpServletResponse:

Web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的对象HttpServletResponse

  • 如果需要获取客户端请求过来的参数:使用HttpServletRequest
  • 如果要给客户端响应一些信息:使用HttpServletResponse

1.简单分类:

向浏览器发送数据的方法:

ServletOutStream getOutStream() throws IOException;
PrintWrite getWriter() throws IOEception;

向浏览器发送响应头的方法:

响应的状态码:

2.下载文件:

  • 向浏览器输出信息
  • 下载文件
  • 要获取下载文件路径
  • 下载文件名称
  • 设置让浏览器能够支持下载的文件内容
  • 获取下载文件的输入流
  • 创建缓冲区
  • 获取OutputStream对象
  • 将FileOutputStream流写入到buffer缓冲区
  • 使用OutputStream将缓冲区中的数据输出到客户端
package com.krian.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 19:59
 * @Tip: Keeping the eyes of the prize !
 * @Description: 文件下载!!!
 */
@SuppressWarnings({"all"})
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取下载文件路径:
        String url = "C:\\Users\\L\\Desktop\\JavaWeb\\No03_Response_Servlet\\src\\main\\resources\\OIP.jpg"; //这里使用的绝对路径
        System.out.println("文件下载地址:" + url);
        //2.下载文件名称:
        String fileName = url.substring(url.lastIndexOf("\\") + 1);
        //3.设置想办法让浏览器能够支持文件的下载(Content-Disposition),中文文件名URLEncoder.encode编码,否则有可能乱码
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //4.获取下载文件的输入流
        FileInputStream fileInputStream = new FileInputStream(url);
        //5.创建缓存区:
        int len = 0;
        byte[] buffer = new byte[1024];
        //6.获取OutputStream对象
        ServletOutputStream outputStream = resp.getOutputStream();
        //7.将FileOutputStream流写入到buffer缓冲区中,使用OutputStream将缓冲区中的数据输出到客户端
        while ((len = fileInputStream.read(buffer)) > 0){
            outputStream.write(buffer,0,len);
        }
        //8.关闭输入输出流
        fileInputStream.close();
        outputStream.close();
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

3.验证码:

package com.krian.Servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-04 20:22
 * @Tip: Keeping the eyes of the prize !
 * @Description:
 */
public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置浏览器刷新:
        resp.setHeader("refresh","5");
        //在内存中创建一张图片:
        BufferedImage image = new BufferedImage(100,30,BufferedImage.TYPE_INT_RGB);
        //获取图片:
        Graphics2D graphics2D = (Graphics2D) image.getGraphics();
        //设置图片背景颜色:
        graphics2D.setColor(Color.CYAN);
        graphics2D.fillRect(0,0,100,30);
        //给图片写入数据:
        graphics2D.setColor(Color.DARK_GRAY);
        graphics2D.setFont(new Font(null,Font.BOLD,25));
        graphics2D.drawString(makeNumber(),0,30);
        //声明浏览器,使用这个请求方式打开:
        resp.setContentType("image/jpeg");
        //浏览器存在缓存,清除浏览器缓存:
        resp.setDateHeader("Expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
        //输出图片到浏览器:
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }
    private String makeNumber(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0 ; i < 7 - num.length();i++){
            sb.append("0");
        }
        return num;
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

4.实现重定向:

B有一个Web资源收到客户端A的请求后,B会通知A客户端去访问另外一个Web资源C,这个过程叫做重定向

常见场景:

  • 登陆注册
package com.krian.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @Author: Lunaticer
 * @Create: 2021-06-05 0:09
 * @Tip: Keeping the eyes of the prize !
 * @Description:
 */
@SuppressWarnings({"all"})
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //重定向:
        resp.sendRedirect("/image");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

面试题:请你聊聊重定向和转发的区别:

相同点:

  • 页面都会发生跳转

不同点:

  • 请求转发的时候,url不会发生改变
  • 重定向的时候,url地址栏会发生变化

HttpServletRequest:

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest。

1.通过HttpServletRequest获取前端参数和转发请求:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    String[] hobbys = req.getParameterValues("hobbys");
    System.out.println("=============================");
    //后台接收中文乱码问题
    System.out.println(username);
    System.out.println(password);
    System.out.println(Arrays.toString(hobbys));
    System.out.println("=============================");
    System.out.println(req.getContextPath());
    //通过请求转发
    //这里的 / 代表当前的web应用
    req.getRequestDispatcher("/success.jsp").forward(req,resp);
}


相关文章
|
7天前
|
容器
Servlet 教程 之 Servlet 编写过滤器 6
该教程介绍了如何在Servlet中编写过滤器。可以创建多个过滤器,如AuthenFilter和LogFilter,并通过不同的映射进行配置。过滤器的应用顺序由web.xml中filter-mapping的顺序决定,可通过调整顺序改变过滤器执行的先后。
10 3
|
9月前
|
存储 Java 数据安全/隐私保护
servlet过滤器与监听器
前言 Servlet 过滤器和监听器是 Java Web 应用程序中常见的两种组件,它们提供了各种扩展 Web 应用程序功能的方式。 总的来说,过滤器和监听器都可以通过 Java Web 应用程序的配置文件或注解进行使用,方便灵活,并可以很好地实现框架与业务逻辑的分离,提高代码可维护性和扩展性。 过滤器(Filter) 1. 参数验证和转换:可以拦截用户提交的数据,并对数据格式进行验证、修正或转换。 2. 访问控制和认证:可以拦截请求并检查用户是否有访问特定资源的权限。 3. 日志记录:可以拦截请求并输出相应的日志信息,用于系统运行时的监测与故障排除。 4. 资源压缩和解密: 可以拦截响应并对
49 0
|
11月前
|
Java 数据安全/隐私保护
【Java Web编程 十】深入理解Servlet过滤器
【Java Web编程 十】深入理解Servlet过滤器
92 0
|
12月前
|
Java 容器
Servlet 过滤器方法
Servlet 过滤器方法
55 0
|
12月前
|
XML Java 数据安全/隐私保护
JSP 和 Servlet 中的过滤器都是 Java 类。
JSP 和 Servlet 中的过滤器都是 Java 类。
60 0
Servlet学习——过滤器
Servlet学习——过滤器
47 0
|
1月前
|
Java
学校教师管理系统【JSP+Servlet+JavaBean】(Java课设)
学校教师管理系统【JSP+Servlet+JavaBean】(Java课设)
21 1
|
1月前
|
Java
人事管理系统【JSP+Servlet+JavaBean】(Java课设)
人事管理系统【JSP+Servlet+JavaBean】(Java课设)
19 0
|
2月前
使用Servlet上传多张图片——前台页面层(Index.jsp)
使用Servlet上传多张图片——前台页面层(Index.jsp)
14 0
|
7天前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式