目录
一、Servlet技术
1.什么是Servlet
- Servlet是JaveEE规范之一,规范就是接口
- Servlet是JavaWeb三大组件之一。(Servlet、Filter、Listener)
- Servlet是运行在服务器上的java程序,
可以用来接收客户端发送过来的请求,并响应数据给客户端。
2.实现
- 声明类实现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 标签给Tomcat 配置Servlet 程序-->
<servlet>
<!--servlet-name 标签Servlet 程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class 是Servlet 程序的全类名-->
<servlet-class>com.dxs.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping 标签给servlet 程序配置访问地址-->
<servlet-mapping>
<!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个Servlet 程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern 标签配置访问地址<br/>
/ 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径<br/>
/hello 表示地址为:http://ip:port/工程路径/hello <br/>
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
public class HelloServlet implements Servlet {
/**
* service 方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws
ServletException, IOException {
System.out.println("Hello Servlet");
}
}
3. URL到Servlet的访问过程
- 通过ip地址定位到服务器
- 通过port端口定位到Tomcat
- 通过工程路径确定到指定工程
- 通过资源路径(即web.xml中的
<url-pattern>
)得到Servlet程序的名称(即<servlet-name>
) - 通过
<servlet-mapping>
标签中的Servlet程序名称可以找到相同名称的<servlet>
,进而得到其中的<servlet-class>
,定位到指定类去处理请求。
4.Servlet的生命周期
- 执行Servlet构造方法
- 执行init()初始化方法
- 执行service()方法
- 执行destroy()方法
1和2都是在Servlet程序第一次创建时调用,3是每次访问Servlet时都会调用,4是web工程停止时调用。
5.Get和Post请求的分发处理
public class HelloServlet implements Servlet {
/**
* service 方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws
ServletException, IOException {
// 类型转换(因为它有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取客户端的请求的方式
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
/**
* 做get 请求的操作
*/
public void doGet(){
System.out.println("get 请求");
}
/**
* 做post 请求的操作
*/
public void doPost(){
System.out.println("post 请求");
}
}
6.HttpServlet
一般在实际项目开发中,都是使用继承HttpServlet 类的方式去实现Servlet 程序。
实现:
- 声明类并继承HttpServlet类
- 更具需求重写doGet和doPost方法
- 在web.xml中配置Servlet程序
public class HelloServlet2 extends HttpServlet {
/**
* doGet()在get 请求的时候调用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
System.out.println("HelloServlet2 的doGet 方法");
}
/**
* doPost()在post 请求的时候调用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
System.out.println("HelloServlet2 的doPost 方法");
}
}
7.Servlet类的继承体系
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);
}
}
根据上面的doGet源码可以看出,HttpServlet类的方法只负责了抛出异常
,所以重写这些方法时一定不要加super.doGet(req, resp)
二、ServletConfig类
作用:
- 获取Servlet程序的名称,即servlet-name的值
- 获取初始化参数init-param
- 获取ServletContext对象
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.dxs.servlet.HelloServlet</servlet-class>
<!--init-param 是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>username</param-name>
<!--是参数值-->
<param-value>root</param-value>
</init-param>
<!--init-param 是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>url</param-name>
<!--是参数值-->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
@Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);//一定要有,应为用通过父类初始化方法初始化servletConfig对象
// 1、可以获取Servlet 程序的别名servlet-name 的值
System.out.println("HelloServlet 程序的别名是:" + servletConfig.getServletName());
// 2、获取初始化参数init-param
System.out.println("初始化参数username 的值是;" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数url 的值是;" + servletConfig.getInitParameter("url"));
// 3、获取ServletContext 对象
System.out.println(servletConfig.getServletContext());
}
三、ServletContext类
1.什么是ServletContext
- ServletContext 是一个接口,它表示Servlet 上下文对象
- 一个web 工程,只有一个ServletContext 对象实例。
- ServletContext 对象是一个域对象。(域对象,是可以像Map一样存取数据的对象。这里的域指的是存取数据的操作范围,即整个web 工程。)
- ServletContext 是在web 工程部署启动的时候创建。在web工程停止的时候销毁。
2.ServletContext类作用
- 获取web.xml 中配置的上下文参数context-param
- 获取当前的工程路径,格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像Map 一样存取数据
<!--context-param 是上下文参数(它属于整个web 工程)-->
<context-param>
<param-name>username</param-name>
<param-value>dxs</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>12345</param-value>
</context-param>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext 对象
//ServletContext context = getServletContext();
ServletContext servletContext = getServletConfig().getServletContext();
System.out.println(servletContext.getInitParameter("username"));
System.out.println(servletContext.getInitParameter("password"));
System.out.println(servletContext.getRealPath("/"));
}
四、Http协议
HTTP协议,就是指客户端和服务器之间通信时,发送的数据,处理事件,需要遵守的规则。HTTP 协议中的数据又叫报文。
1.请求报文
Get请求
- 请求行
(1) 请求的方式GET
(2) 请求的资源路径[+?+请求参数]
(3) 请求的协议的版本号HTTP/1.1 - 请求头
key : value 组成不同的键值对,表示不同的含义。
GET 请求的特点是:
- 浏览器地址栏中的地址是:action 属性[+?+请求参数]
请求参数的格式是:name=value&name=value - 不安全
- 它有数据长度的限制
Post请求
- 请求行
(1) 请求的方式POST
(2) 请求的资源路径[+?+请求参数]
(3) 请求的协议的版本号HTTP/1.1 - 请求头
(1) key : value 不同的请求头,有不同的含义
空行
- 请求体:发送给服务器的数据
POST 请求的特点是:
- 浏览器地址栏中只有action 属性值
- 相对于GET 请求要安全
- 理论上没有数据长度的限制
两种请求的分类
Get请求有哪些:
- form 标签method=get
- a 标签
- link 标签引入css
- Script 标签引入js 文件
- img 标签引入图片
- iframe 引入html 页面
- 在浏览器地址栏中输入地址后敲回车
Post请求有哪些:
- form 标签method=post
2.响应报文
- 响应行
(1) 响应的协议和版本号
(2) 响应状态码
(3) 响应状态描述符 - 响应头
(1) key : value 不同的响应头,有其不同含义
空行 - 响应体:回传给客户端的数据
常用响应码:
- 200 表示请求成功
- 302 表示请求重定向
- 404 表示请求服务器已经收到了,请求资源不存在
- 500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
3.MIME类型说明
MIME 是HTTP 协议中数据类型。
MIME 的英文全称是"Multipurpose Internet Mail Extensions" (多功能Internet 邮件扩充服务)。MIME 类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
五、HttpServletRequest类
1.HttpServletRequest类的作用
每次只要有请求进入Tomcat 服务器,Tomcat 服务器就会把请求过来的HTTP 协议信息解析好封装到Request 对象中。然后传递到service 方法(doGet 和doPost)中给我们使用。我们可以通过HttpServletRequest 对象,获取到所有请求的信息。
2.HttpServletRequest类常用方法
- getRequestURI() 获取请求的资源路径
- getRequestURL() 获取请求的统一资源定位符(绝对路径)
- getRemoteHost() 获取客户端的ip 地址
- getHeader() 获取请求头
- getParameter() 获取请求的参数
- getParameterValues() 获取请求的参数(多个值的时候使用)
- getMethod() 获取请求的方式GET 或POST
- setAttribute(key, value); 设置域数据
- getAttribute(key); 获取域数据
- getRequestDispatcher() 获取请求转发对象
请求的中文乱码问题:
// 设置请求体的字符集为UTF-8,从而解决post 请求的中文乱码问题
req.setCharacterEncoding("UTF-8");
3.请求的转发
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("在Servlet1查看参数:"+username);
//resp.setCharacterEncoding("UTF-8");
//resp.setHeader("Context-Type","text/html,charset=UTF-8");
resp.setContentType("text/html,charset=UTF-8");
req.setAttribute("key","Servlet1");
//请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA 代码的web 目录
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
requestDispatcher.forward(req,resp);
}
}
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("在Servlet2查看参数:"+username);
Object key = req.getAttribute("key");
System.out.println(key);
}
}
特点:
- 浏览器地址栏不会改变
- 只进行一次请求,即req是相同的,这样getAttribute才可以取出相同的数据
- 共享Request域中的数据
- 可以转发访问到WEB-INF目录下的资源
- 不可以访问工程外的资源,因为getRequestDispatcher参数的目录结构决定其所在工程
4.base标签作用
base标签可以设置当前界面所有相对路径工作时,参照哪个路径进行跳转。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--base 标签设置页面相对路径工作时参照的地址
href 属性就是参数的地址值
-->
<base href="http://localhost:8080/servlet/a/b/">
</head>
<body>
这是a 下的b 下的c.html 页面<br/>
<a href="../../index.html">跳回首页</a><br/>
<!-- ..返回上层目录的参照路径是base设置的路径-->
</body>
</html>
5.相对路径和绝对路径
在javaWeb 中,路径分为相对路径和绝对路径
- 相对路径
. 表示当前目录
. . 表示上一级目录
资源名 表示当前目录下的资源 - 绝对路径
http://ip:port/工程路径/资源路径
6.web中/的不同意义
在web 中/ 斜杠是一种绝对路径。
- / 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
- / 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
1、< url-pattern >/servlet1< /url-pattern >
2、servletContext.getRealPath(“/”);
3、request.getRequestDispatcher(“/”); - 特殊:response.sendRediect(“/”),把斜杠发送给浏览器解析。得到的地址是http://ip:port/
六、HttpServletResponse类
1.HttpServletResponse类作用
HttpServletResponse 类和HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个Response 对象传递给Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse 对象来进行设置。
2.输入流
字节流:使用getOutputStream()得到。常用于下载(传递二进制数据)
字符流:getWriter()。常用于回传字符串(常用)
两个流同时只能使用一个
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 设置服务器字符集为UTF-8
//resp.setCharacterEncoding("UTF-8");
// 通过响应头,设置浏览器也使用UTF-8 字符集
//resp.setHeader("Content-Type", "text/html; charset=UTF-8");
//解决写道浏览器显示的乱码问题
// 它会同时设置服务器和客户端都使用UTF-8 字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html; charset=UTF-8");
//往客户端回传字符串数据
PrintWriter writer = resp.getWriter();
writer.write("响应");
}
}
3.请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。
// 设置响应状态码302 ,表示重定向
resp.setStatus(302);
// 设置响应头,说明新的地址在哪里
resp.setHeader("Location","http://localhost:8080");
//推荐使用
resp.sendRedirect("http://localhost:8080");
特点:
- 浏览器地址栏会发生变化
- 这是两次请求
- 不会共享Request域的数据(因为是两个请求对象)
- 不能访问WEB-INF目录资源
- 可以访问工程外资源(sendRedirect参数是绝对路径)