文章目录
一.Servlet
1.Servlet概念
(1).是JavaEE规范之一,规范就是接口
.
(2).是JavaWeb三大组件之一,三大组件分别是:Servlet程序、Filter过滤器、Listener监听器.
(3).是运行在服务器上的一个java小程序
,它可以接收客户端发送过来的请求,并响应数据给客户端.
2.手动实现
Servlet程序
(1).编写一个类去实现Servlet接口
.
(2).实现service方法
,处理请求并响应数据.
package com.servlet;
import javax.servlet.*;
import java.io.IOException;
public class HelloServlet implements Servlet{
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
(3).到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标签给Tomcat配置Servlet程序-->
<servlet>
<!--servlet-name标签给Servlet程序起一个别名(一般是类名)-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class标签是Servlet程序的全类名-->
<servlet-class>com.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping标签给Servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签告诉服务器当前配置的地址给哪个Servlet程序用-->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern标签配置访问地址-->
<!--/斜杠 在服务器解析的时候,表示地址为:http://ip:port/工程路径
/hello表示地址为:http://ip:port/工程路径/hello-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
3.Servlet程序常见错误
(1).url-pattern
中配置的路径没有以斜杠打头.
(2).servlet-name
配置的值不存在.
(3).servlet-class
标签的全类名配置错误.
4.url地址到Servlet程序的访问
5.Servlet的生命周期
(1).执行Servlet构造器方法
.
(2).执行init初始化方法
.
(3).执行service方法
.
(4).执行destroy销毁方法
.
注意:
- 第一、二步,是在第一次访问的时候创建Servlet程序会调用.
- 第三步,每次访问都会调用.
- 第四步,在web工程停止的时候调用.
6.GET和POST请求的分发处理
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet");
//类型转换(因为HttpServletRequest中有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
//获取请求的方式
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
public void doGet(){
System.out.println("get请求");
}
public void doPost(){
System.out.println("post请求");
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/06_servlet/hello" method="GET">
<input type="submit">
</form>
</body>
</html>
7.通过继承HttpServlet实现Servlet程序
这种方式在开发中比较常用
(1).编写一个类去实现HttpServlet类
.
(2).根据业务需要重写doGet或doPost方法
.
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 get");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 post");
}
}
(3).到web.xml中配置Servlet程序的访问地址
.
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
8.IDEA菜单生成Servlet程序
9.整个Servlet类的继承体系
二.ServletConfig类
是Servlet程序的配置信息类.
Servlet程序和ServletConfig对象,都是由Tomcat负责创建,我们负责使用.
Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象(一个ServletConfig仅对应一个Servlet程序
)ServletConfig类的三大作用
(1).获取对应Servlet程序
的别名servlet-name
的值.
(2).获取对应Servlet程序
的初始化参数init-param
.
(3).获取ServletContext对象
.
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());
System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url的值是:" + servletConfig.getInitParameter("url"));
System.out.println(servletConfig.getServletContext());
}
<!--init-param是初始化参数-->
<init-param>
<!--param-name是参数名-->
<param-name>username</param-name>
<!--param-value是参数值-->
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
注意:
我们重写init()方法时,需要先写一条调用父类init()方法的语句.
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("11111");
}
三.ServletContext类
1.ServletContext的概念
(1).是一个接口,它表示Servlet上下文对象.
(2).是一个web工程,只有一个ServletContext对象实例.
(3).是一个域对象.
(4).是在web工程部署启动的时候创建,在web工程停止的时候销毁.
域对象:
是可以像Map一样存取数据
的对象,这里的域
指的是存取数据的操做范围
.
存数据: setAttribute() 取数据: getAttribute() 删除数据: removeAttribute()
2.ServletContext类的四个作用
(1).获取web.xml中配置的上下文参数context-param.
(2).获取当前的工程路径,格式:/工程路径.
(3).获取工程部署后在服务器硬盘上的绝对路径.
package com.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;
public class ContextServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("username的值" + username);
System.out.println("password的值" + context.getInitParameter("password"));
System.out.println("当前工程路径:" + context.getContextPath());
System.out.println("工程部署的路径:" + context.getRealPath("/"));//映射到IDEA的web目录
System.out.println("工程部署的路径:" + context.getRealPath("/images"));
}
}
(4).像Map一样存取数据.
package com.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;
public class ContextServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println("保存前" + context.getAttribute("k1"));
context.setAttribute("k1","v1");
System.out.println("Context1中获取k1的值是:" + context.getAttribute("k1"));
}
}
四.HTTP协议
1.HTTP协议:客户端和服务器之间通信时发送的数据(又叫报文),需要遵守的规则.
2.请求的HTTP协议格式
客户端给服务器发送数据叫请求.
服务器给客户端回传数据叫响应.
请求分为GET请求和POST请求两种.
GET请求
请求行
(1).请求的方式:GET
(2).请求的资源路径[+?+请求参数]
(3).请求的协议的版本号:HTTP/1.1.请求头
:key : value 组成,不同的键值对,表示的含义不同.
POST请求
请求行
(1).请求的方式:POST.
(2).请求的资源路径[+?+请求参数].
(3).请求的协议的版本号:HTTP/1.1.请求头:
key:value 不同的请求头,有不同的含义.空行
请求体:
发送给服务器的数据.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/06_servlet/hello2" method="post">
<inout type="hidden" name="action" value="login" />
<inout type="hidden" name="username" value="root" />
<input type="submit">
</form>
</body>
</html>
常用请求头的说明
Accept:
表示客户端可以接收的数据类型.
Accept-Languege:
表示客户端可以接收的语言类型.
user-Agent:
表示客户端浏览器的信息.
Host:
表示请求时的服务器ip和端口号.GET请求与POST请求的划分
GET请求有:
(1).form标签 method=get
(2).a标签
(3).link标签引入css
(4).Script标签引入js文件
(5).img标签引入图片
(6).iframe引入html页面
(7).在浏览器地址栏中引入地址后敲回车POST请求有:
form标签 method=get
3.响应的HTTP协议格式
响应行
(1).响应的协议和版本号: HTTP/1.1
(2).响应状态码
(3).响应状态描述符响应头:
key:value 不同的响应头,有其不同的含义空行
响应体
回传给客户的程序
4.常用响应码说明
200 表示请求成功
302 表示请求重定向
404 表示服务器已经收到请求,但是需要的数据不存在或者请求地址错误
500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
5.MIME类型说明
(1).概念:MIME(多功能Internet邮件扩充服务)是HTTP协议中的数据类型
(2).格式:大类型/小类型,并与某一种文件的扩展名相对应.
在浏览器查看HTTP协议:
启动部署项目后,发出请求,然后按F12在网络部分就能看到了.
五.HttpServletRequest类
1.HttpServletRequest类的作用:
每次只要进入Tomcat服务器
,Tomcat服务器就会把请求过来的HTTP协议
信息解析好封装到Request对象中.然后传递到service方法(doGet和doPost)中给我们使用,我们可以通过HttpServletRequest对象
,获取到所有请求的信息
.
2.HttpServletRequest类的常用方法
(1).getRequestURI(); 获取请求的资源路径
(2).getRequestURL(); 获取请求的统一资源定位符(绝对路径)
(3).getRemoteHost(); 获取客户端的ip地址
(4).getHeader(); 获取请求头
(5).getMethod(); 获取请求的方式(GET/POST)
(6).getParameter(); 获取请求的参数
(7).getParameterValues(); 获取请求的参数(多个值时使用)
(8).setAttribute(key,value); 设置域数据
(9).getAttribute(key); 获取域数据
(10).getRequestDispatcher(); 获取请求转发对象
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//getRequestURI()
System.out.println("URI: " + req.getRequestURI());
//getRequestURL()
System.out.println("URL: " + req.getRequestURL());
//getRemoteHost()
System.out.println("客户端ip地址: " + req.getRemoteHost());
//getHeader()
System.out.println("请求头: " + req.getHeader("User-Agent"));
//getMethod()
System.out.println("请求方式: " + req.getMethod());
}
}
3.获取请求参数
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("用户名: " + username);
System.out.println("密码: " + password);
System.out.println("兴趣爱好: " + Arrays.asList(hobby));
}
<form action="http://localhost:8080/07_servlet/parameterServlet" method="get">
用户名:<input type="text" name="username"></br>
密码: <input type="password" name="password"></br>
兴趣爱好: <input type="checkbox" name="hobby" value="java">java
<input type="checkbox" name="hobby" value="js">javaScript</br>
<input type="submit">
</form>
注意:
对于Post请求存在中文乱码问题,通过设置请求体字符集编码为UTF-8来解决,而且必须在获取请求参数之前才有效.
//设置请求体的字符集为UTF-8,从而解决Post请求的中文乱码问题
req.setCharacterEncoding("UTF-8");
4.请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet1中查看参数: " + username);
//给材料盖章,并传到Servlet2去查看
req.setAttribute("key","Servlet1的章");
//问Servlet2怎么走
//请求转发必须要以斜杠打头, / 表示地址为:http://ip:port/工程名/,映射到IDEA代码的web目录
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
//去Servlet2
requestDispatcher.forward(req,resp);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet2中查看参数: " + username);
//查看是否有Servlet1的盖章
Object key = req.getAttribute("key");
System.out.println("Servlet1是否有盖章: " + key);
//处理自己的业务
System.out.println("Servlet2处理自己的业务");
}
注意:
不可以访问工程以外的资源
5.base标签的作用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
web下的index.html<br/>
<a href="a/b/c.html">a/b/c.html</a><br/>
<a href="http://localhost:8080/07_servlet/fowarC">请求转发:a/b/c.html</a>
</body>
</html>
public class FowarC extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("经过了Fowrd");
req.getRequestDispatcher("/a/b/c.html").forward(req,resp);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--base标签设置当前页面相对路径工作时的参照地址
c.html可以省略-->
<base href="http://localhost:8080/07_servlet/a/b/c.html">
</head>
<body>
这是a/b/c.html页面</br>
<a href="../../index.html">跳回首页</a>
</body>
</html>
6.Web中的相对路径和绝对路径
在JavaWeb中路径分为相对路径和绝对路径:
相对路径:
.
表示当前目录
..
表示上一级目录
资源名 表示当前目录/资源
绝对路径:
http://ip:port/工程路径/资源路径
7.Web中 / 斜杠的不同意义
在Web中 / 斜杠 是一中绝对路径.
如果被浏览器解析,得到的地址是:http://ip:port/
例如:
如果被服务器解析,得到的地址是:http://ip:port/工程路径
例如:
六.HttpServletResponse类
1.HttpServletResponse类的作用:
- 和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用.
- HttpServletRequest表示请求过来的信息
- HttpServletResponse表示所有响应的信息
- 如果需要设置返回给客户端的信息,可以通过HttpServletResponse对象来进行设置
2.两个输出流的说明
- 字节流 getOutputStream() 常用于下载(传递二进制数据)
- 字符流 getWriter() 常用于回传字符串(常用)
注意:
两个输出流只能同时使用一个
3.往客户端回传数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("wyl");
}
4.响应的乱码的解决
第一种方式:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//此方法一定要在获取流对象之前调用才有效
//设置服务器字符集为UTF-8
resp.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器也使用UTF-8字符集
resp.setHeader("Content-Type","text/html;UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("王");
}
}
第二种方式:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//此方法一定要在获取流对象之前调用才有效
//同时设置服务器和浏览器字符集为UTF-8
resp.setContentType("text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("王");
}
5.请求重定向
概念:
是指客户端给服务器发请求,然后服务器告诉客户端一个新地址
,要求客户端去新地址访问(之前的地址可能被废弃)
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("曾到此一游");
req.setAttribute("key","value");
//设置响应状态码302,表示重定向,(已搬迁)
resp.setStatus(302);
//设置响应头,说明新的地址在哪
resp.setHeader("Location","http://localhost:8080/07_servlet/response2");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object key = req.getAttribute("key");
System.out.println(key);
resp.getWriter().write("result");
}
请求重定向的第二种方案:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("曾到此一游");
req.setAttribute("key","value");
resp.sendRedirect("http://localhost:8080/07_servlet/response2");
}