整体介绍
一、HTTP
HTTP协议:浏览器和服务器之间传输数据的规则。
(一)请求数据格式
(二)响应数据格式
常见响应状态码
状态码大全
二、Tomcat
Web服务器:是一个应用程序,对HTTP协议的操作进行了封装,使得我们不必直接对协议进行操作,让web开发更加便捷。
以Tomcat为例,将写好的Web项目放在Tomcat中,就可以让外界访问这个页面,而不必去关心协议的操作。
简单来说Web服务器的作用:
- 封装HTTP协议操作,简化开发。
- 将Web项目部署到服务器中,对外提供网上浏览服务。
(一)简介
- 是一个开源免费的轻量级Web服务器,支持Servlet/JSP这些少量的JAVAEE规范。
- Tomcat也被称为Web容器、Servelet容器。Servelet需要依赖于Tomecat运行。
(二)基本使用
官网下载
注:启动时一闪而过,可能是JAVA的环境变量没有正确配置,检查下。
(1)配置
(2)部署
(三)IDEA中创建Maven Web项目
创建Maven Web的两种方式
解决IDEA 2021 新建Maven项目没有archetype模板
(四)IDEA中使用Tomcat
(1)集成本地Tomcat
(2)Tomcat Maven插件
注意:此插件目前只支持到Tomcat7!
首先alt+ins>>Plugin Template快速生成模板
三、Servlet
- Servelet是Java提供的一门动态Web资源开发技术。
- 我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。
(一)快速入门
(二)执行流程
简单说明:
- 首先通过不带地址的url找到Tomcat服务器。
- 然后找到Web服务器下的web-demo这个web项目。
- 最后/demo找到具体的web资源。
- Servlet对象是由Web服务器来new的(什么时候new这个Servlet对象,就是下面生命周期的内容)。
(三)生命周期(重点)
Servlet重写的五个方法
(四)体系结构
前言:
- 一般情况下我们只会使用到Servlet中的service()方法,并且在service()方法中去判断客户端用的是Get还是Post请求,这有些繁琐,所以诞生了HttpServlet。
- HttpServlet间接重写了Servlet接口,作用是自动判断客户端用的是Get请求还是Post请求或者其他请求方式,然后调用对应的doGet()或doPost()。对于我们,只需要在对应的方法中写好处理方式就可以了。
示例:
自定义类去继承HttpServlet:
@WebServlet(urlPatterns = "/demo02",loadOnStartup = 1)
public class ServletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet....");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost....");
}
}
webapp下新建一个html,模拟post请求(注意action是提交到demo02下,这样我们自定义的类就可以处理过来的请求):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>实验</title>
</head>
<body>
<form action="/MavenWeb01_war/demo02" method="post">
<input name="name"><input type="submit">
</form>
</body>
</html>
(五)urlPattern配置
(六)XML配置方式编写Servlet(老版)
Servlet从3.0版本开始支持使用注解配置,3.0版本之前只支持XML配置文件的配置方式
四、Request和Response
Request:获取请求数据
Response:设置响应数据
(一)Request
(1)继承体系
(2)获取请求数据
一般情况
使用通用方式获取请求参数(POST、GET都一样的获取方式)
- 在doGet()方法中写方法体
- 在doPost()方法中将自己的形参传入doGet()就行了
this.doGet(req, resp);
- 这样多个请求格式只需要在一个请求方法中写方法体就行了(因为不同的请求方法只有一个区别:有请求体和没有请求体;其余的代码都相似)
- 下面这三个方法,重点:
IDEA模板快速创建Servlet
中文请求乱码处理
注意:Tomcat8.0之后解决了中文乱码问题,将默认解码方式从ISO-8859-1改为了UTF-8。
-
产生乱码的原因:
A. 浏览器编码时采用UTF-8的URL编码,传到Tomcat服务器后Tomcat使用ISO-8859-1的URL解码,编码和解码不一致就导致了乱码。
B. 虽然Tomcat解析出来的是乱码,但底层的字节数组是对的,只是解码有错。所以思路是将乱码的字符串先转为字节数组,再使用String构造方法指定编码方式转为String类型的字符串。
-
解决乱码
A. POST解决乱码:request.setCharacterEncoding("UTF-8");
设置字符输入流的编码(因为POST请求获取数据底层是用的字符输入流.getReader),这种方式只能用于Post乱码。
B. GET解决乱码,通用解决方式,POST也可以用:
//先将username转为为字节数组
byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
//使用String构造方法修改编码方式
String encodingUsername = new String(bytes, StandardCharsets.UTF_8);
- URL编码实现方式(URL工具类)
A. 编码:URLEncoder.encode(str,"utf-8");
B. 解码:URLDecoder.decode(str,"ISO-8859-1");
(3)请求转发
第一步是将自己的两个对象传给其他资源。
第二步是将共享的数据存储到自身的request域中,然后可以使用 第一步将共享数据发送出去。
-
服务器内部资源的跳转方式:
request.getRequestDispatcher("目标路径,如/demo03").forward(request,response);
将自己的request和response对象转发给目标路径的Servlet对象。 -
不同资源间(如/demo01和/dmo02)共享数据,使用Request对象。
eg:将/demo04的资源发送给/demo05
//'/demo04'里,存储数据到Request域中
request.setAttribute("username", "张三");
//发送
request.getRequestDispatcher("/demo05").forward(request, response);
// '/demo05'里,接收数据
Object username = request.getAttribute("username");
System.out.println("demo05..." + (String) username);
(二)Response
(1)常用方法
(2)Response重定向
两种重定向方式
//重定向方式1
//设置响应状态码
response.setStatus(302);
//设置响应头,重定向的路径必须写上虚拟目录+资源路径
response.setHeader("Location", "/MavenWeb01/ResponseDemo02");
//重定向方式二,简便方式
response.sendRedirect("/MavenWeb01/ResponseDemo02");
重定向与请求转发之前的特点完全相反,注意区别。
(3)路径问题
动态获取虚拟路径:request.getContextPath();
(4)响应字符数据
示例:
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("你好,哈喽~");
writer.write("<h1>hello,字符</h1>");
(5)响应字节数据
eg:响应一张图片
- 不使用工具类的方式
//1.读取本地文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Project\\MavenWeb01\\src\\main\\resources\\12.jpg"));
//2.字节输入流,输出流对拷
ServletOutputStream os = response.getOutputStream();
//不使用工具类,读文件
int len;
byte[] bytes = new byte[1024];
while ((len = bis.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
bis.close();
- 使用IOUtils工具类
//1.读取本地文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Project\\MavenWeb01\\src\\main\\resources\\12.jpg"));
//2.字节输入流,输出流对拷
ServletOutputStream os = response.getOutputStream();
//使用工具类
IOUtils.copy(bis, os);
bis.close();