当前位置:网站首页>Servlet详解含实例
Servlet详解含实例
2022-08-03 05:27:00 【耳冉鹅】
一、简介
- Servlet是sun公司开发动态web的一门技术
- Sun在这些API中提供了一个接口叫做:Servlet,若想要开发一个Servlet程序,只需要完成两个小步骤:
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器中
把实现了Servlet接口的Java程序叫做 Servlet
二、HelloServlet
Servlet接口在Sun公司有两个默认的实现类:HttpServlet、GenericServlet
1、构建项目
构建一个普通的Maven项目,删掉里面的src目录,然后在项目中建立Model
这个空的工程就是Maven主工程
2、父子工程理解
父项目中:
<modules>
<module>servlet-01</module>
</modules>
子项目中:

<parent>
<artifactId>javaweb-02-servlet</artifactId>
<groupId>com.erran</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的java子项目可以直接使用
son extends father
3、环境优化
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">
<display-name>Archetype Created Web Application</display-name>
</web-app>
将Maven结构搭建完整
4、编写Servlet程序
- 编写一个普通类
- 实现Servlet接口,直接继承HTTPServlet
package com.erran.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 erran */
public class HelloServlet extends HttpServlet {
// get、post只是请求实现的不同方式,因此可以相互调用且业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 响应流
PrintWriter writer = resp.getWriter();
writer.println("HelloServlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
5、编写Servlet映射
为什么需要映射
Java程序需要通过浏览器访问,而浏览器需要连接web服务器,因此需要在web服务中注册所写的Servlet,还需要给浏览器一个能够访问的路径
web.xml中添加
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.erran.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
6、配置Tomcat
注意:配置项目发布的路径

7、启动测试


执行过程:http://localhost:8080/s1/hello执行的是下面代码中的url-pattern,继而去寻找servlet-name
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
从servlet-mapping转到servlet中,对应servlet-name,因此去寻找servlet-class,即我们所写的HelloServlet
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.erran.servlet.HelloServlet</servlet-class>
</servlet>
进入到doGet方法,打印“HelloServlet”,完成执行
三、Servlet原理
Servlet是由Web服务器调用,web服务器在收到浏览器请求后,会:

- Request会从service(请求)拿到请求并把请求之后的响应交给Response
- 我们编写的实现类重写这些方法
- 接收并处理请求
- 给出响应的信息
四、Mapping
一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
自定义后缀实现请求路径**(前面不能加项目映射的路径)*
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
优先级问题
指定了固定的映射路径优先级最高,若找不到则走默认的处理请求
五、ServletContext
web容器在启动的时候,会为每个web程序都创建一个对应的ServletContext对象,代表了当前的web应用
1、共享数据
在这个Servlet中保存的数据,可以在另一个Servlet上拿到
public class Helloservlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// this.getInitParameter(); 初始化参数
// this.getServletConfig(); Servlet配置
// this.getServletContext(); Servlet上下文
ServletContext servletContext = this.getServletContext();
String username = "名称";
// 将一个数据保存在ServletContext中
servletContext.setAttribute("username", username);
System.out.println("Hello");
}
}
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");
resp.getWriter().println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.erran.servlet.Helloservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>get</servlet-name>
<servlet-class>com.erran.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>get</servlet-name>
<url-pattern>/get</url-pattern>
</servlet-mapping>
</web-app>
2、获取初始化参数
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().println(url);
}
3、请求转发
<servlet>
<servlet-name>demo2</servlet-name>
<servlet-class>com.erran.servlet.Demo2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo2</servlet-name>
<url-pattern>/demo2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.erran.servlet.Demo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
public class Demo2 extends Helloservlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
// 转发的请求路径
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/gp");
// 调用forward实现请求转发
requestDispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
六、HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse
- 若要获取客户端请求过来的参数: HttpServletRequest
- 若要给客户端响应一些信息: HttpServletResponse
1、简单分类
负责向浏览器发送数据的方法
public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
public void setDateHeader(String name, long date);
public void setIntHeader(String name, int value);
public void addHeader(String name, String value);
public void setIntHeader(String name, int value);
public void addIntHeader(String name, int value);
2、常见应用
- 向浏览器输出消息
- 下载文件
- 要获取下载文件的路径
- 下载的文件名
- 设置让浏览器能够支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutputStream将缓冲区中的数据输出到客户端
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String realPath = "E:\\idea\\IntelliJ IDEA Community Edition 2019.3.1\\IdeaProjects\\javaweb-02-servlet\\response\\target\\classes\\1.jpg";
System.out.println("下载路径:" + realPath);
String fileName = realPath.substring(realPath.lastIndexOf('\\') + 1);
resp.setHeader("Content-Disposition","attachment;filename="+fileName);
FileInputStream in = new FileInputStream(realPath);
int len;
byte[] bytes = new byte[1024];
ServletOutputStream outputStream = resp.getOutputStream();
while ((len = in.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
}
in.close();
outputStream.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<servlet>
<servlet-name>filedown</servlet-name>
<servlet-class>com.erran.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filedown</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
</web-app>

3、验证码功能
验证:
- 前端实现
- 后端实现,需要用到Java 的图片类,生产一个图片
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 如何让浏览器5秒自动刷新一次
resp.setHeader("refresh", "3");
// 在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
// 得到图片 --- 笔
Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
// 设置图片的背景颜色
graphics.setColor(Color.white);
graphics.fillRect(0, 0, 80, 20);
// 给图片写数据
graphics.setColor(Color.blue);
graphics.setFont(new Font(null, Font.BOLD, 20));
graphics.drawString(makeNum(), 0, 20);
// 告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpg");
// 网站存在缓存 不让浏览器缓存
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
// 把图片写给浏览器
ImageIO.write(bufferedImage,"jpg", resp.getOutputStream());
}
// 生成随机数
private String makeNum() {
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
stringBuffer.append("0");
}
String s1 = stringBuffer.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.erran.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/img</url-pattern>
</servlet-mapping>
4、重定向
一个web资源收到客户端请求后,会通知客户端去访问另外一个web资源,这个过程叫做重定向
场景:
- 用户登录
public void sendRedirect(String location) throws IOException;
测试:
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setHeader("Location", "/response");
// resp.setStatus(302);
resp.sendRedirect("/img");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>RedirectServlet</servlet-name>
<servlet-class>com.erran.servlet.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RedirectServlet</servlet-name>
<url-pattern>/Redirect</url-pattern>
</servlet-mapping>
面试题:重定向与转发的区别
- 相同点
- 页面都会实现跳转
- 不同点
- 请求转发的时候,url不会产生变化 307
- 重定向的时候,url地址栏会产生变化 302
七、HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bx3Wodxc-1615873624563)(Servlet.assets/image-20210316132335284.png)]
获取前端传递的参数、请求转发

public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 后台接收中文乱码问题
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobby");
System.out.println("===================");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("===================");
// 页面接收中文乱码问题
resp.setCharacterEncoding("utf-8");
req.getRequestDispatcher("/success.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username"><br>
密码: <input type="password" name="password"> <br>
爱好:
<input type="checkbox" name="hobby" value="抽烟">抽烟
<input type="checkbox" name="hobby" value="喝酒">喝酒
<input type="checkbox" name="hobby" value="烫头">烫头
<br>
<input type="submit">
</form>
</div>
</body>
</html>
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">
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.erran.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
边栏推荐
猜你喜欢

ue4学习日记3(设置操控角色,地形)

Typora

数组与字符串11-反转字符串

VS Project Configuration Manager

ARP协议及简单路由器原理(1)

内网渗透之PPT票据传递攻击(Pass the Ticket)

看了都收藏的3D游戏建模全流程解析,角色模型就该这么做!

Practice of MySql's Sql statement (try how many you can write)

WinServer2012r2破解多用户同时远程登录,并取消用户控制

Automatic ticket issuance based on direct reduction of China Southern Airlines app
随机推荐
ue4学习日记2(项目迁移,画刷,附材质)
9. Please introduce the class loading process, what is the parent delegation model?
classpath: comparison with classpath*
JumpServer如何传输文件以及复制剪切板
go test执行多个文件夹下相同目录的用例
剑指 Offer II 001. 整数除法
使用Powershell批量导入Task
大佬!Maya+ZBrush+Substance制作泰坦野兽全流程!
./autogen.sh: 4: ./autogen.sh: autoreconf: not found
数组与字符串9-翻转字符串里的单词
什么是次世代建模,为什么这么多建模人在学习次世代建模流程
contos安装php-ffmpeg和tp5.1使用插件
2021-06-20
6. What is the difference between Vector, ArrayList and LinkedList?(design, performance, safety)
3D游戏建模师在国内的真实现状,想转行,先来看看!
Unity Animation从UAS获取动画资产到编制状态机控制简单的人物动画
内网渗透之PPT票据传递攻击(Pass the Ticket)
ESXI主机给虚拟机添加USB加密狗设备
【随笔】小马过河
appium(3)webview测试