文章目录
一、servlet 技术
1.1 什么是 Servlet
- Servlet 是 JavaEE 规范之一,规范就是接口
- Servlet 是 JavaWeb 的三大组件之一,三大组件分别为:Servlet 程序、Filter过滤器、Listener监听器
- Servlet 是运行在服务器上的 Java 程序可以接受客户端发来的请求,并相应数据给客户端。
1.2 编写 Servlet 程序
前提:配置 Tomcat 服务器,整合到 idea
-
创建动态web工程
-
编写程序实现 Servlet 接口
package com.study.service;
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;}
/**
* 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 程序被访问!");
}
@Override
public String getServletInfo() { return null; }
@Override
public void destroy() {}
}
- 配置 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 标签给 Tomcat 配置 Servlet 程序 -->
<servlet>
<!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class 是 Servlet 程序的全类名-->
<servlet-class>com.study.service.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>
- 编辑 Tomcat
- 启动Tomcat
浏览器地址栏输入: http://localhost:8080/servletStudy/hello
1.3 url 到 servlet 程序的过程
1.4 Servlet 生命周期
- 执行 Servlet 构造器方法
- 执行 init 初始化方法
第 1、2 步 是在第一次访问的时候,创建Servlet 程序调用 - 执行 Service 方法(每次访问都会调用)
- 执行 destroy 销毁方法(Web工程停止时候调用)
测试
package com.study.service;
import javax.servlet.*;
import java.io.IOException;
public class HelloServlet implements Servlet {
public HelloServlet(){
System.out.println("---构造器---");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("----init()方法---");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig 方法");
return null;
}
/**
* service 方法 是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("---service 方法---");
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo 方法");
return null;
}
@Override
public void destroy() {
System.out.println("---destroy方法---");
}
}
1.5 GET 和 POST 请求分发处理
通过 HttpServletRequest 的 getMethod() 方法,获取请求方式
package com.study.service;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HelloServlet implements Servlet {
public HelloServlet(){}
@Override
public void init(ServletConfig servletConfig) throws ServletException { }
@Override
public ServletConfig getServletConfig() { return null;}
/**
* service 方法 是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet 程序被访问了 ");
// 转换类型 HttpServletRequest 有 getMethod() 方法
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取请求方式
String method = httpServletRequest.getMethod();
System.out.println("请求方式:"+method);
}
@Override
public String getServletInfo() {return null;}
@Override
public void destroy(){ }
}
1.6 继承 HttpServlet 实现 Servlet 程序
一般在实际项目开发中, 都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。
- 编写一个类去继承 HttpServlet 类
- 根据业务需要重写 doGet 或 doPost 方法
- 到 web.xml 中的配置 Servlet 程序的访问地址
servlet程序
package com.study.service;
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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行 GET 方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行 POST 方法");
}
}
通过表单访问
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="/servletStudy/hello" method="post">
<input type="submit" value="提交"></input>
</form>
</body>
</html>
1.7 Servlet 类继承体系
二、ServletConfig 类
ServletConfig 类从类名上来看, 就知道是 Servlet 程序的配置信息类。
Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建, 我们负责使用。
Servlet 程序默认是第一次访问的时候创建, ServletConfig 是每个 Servlet 程序创建时, 就创建一个对应的 ServletConfig 对象。
2.1 ServletConfig 类的三大作用
- 获取程序别名 servlet-name 的值
- 获取初始化参数 init-param
- 获取 servletContext 对象(上下文对象)
配置文件
<?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>HelloServlet</servlet-name>
<servlet-class>com.study.service.HelloServlet</servlet-class>
<!--初始化参数-->
<init-param>
<!--参数名-->
<param-name>username</param-name>
<!--参数值-->
<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>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
servlet 程序
在 init() 方法中可以直接获取 servletConfig 对象
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("-----执行 GET 方法----");
ServletConfig servletConfig = getServletConfig();
String username = servletConfig.getInitParameter("username");
String url = servletConfig.getInitParameter("url");
System.out.println(username+"\n"+url);
System.out.println(servletConfig.getServletContext());
}
}
三、ServletContext 类
3.1 什么是 ServletContext?
- ServletContext 是一个接口,表示 Servlet 上下文对象
- 一个Web工程只有一个 ServletContext 对象实例
- ServletContext 对象是一个域对象
- ServletContext 在Web工程部署时创建,工程停止时销毁。
什么是域对象?
域对象, 是可以像 Map 一样存取数据的对象, 叫域对象。
这里的域指的是存取数据的操作范围, 整个 web 工程。
3.2 ServletContext 类的四大作用
- 获取 web.xml 中配置的上下文参数 context-param
- 获取当前的工程路径, 格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像 Map 一样存取数据
配置文件
<?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>HelloServlet</servlet-name>
<servlet-class>com.study.service.HelloServlet</servlet-class>
</servlet>
<!--配置上下文参数-->
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>pwd</param-value>
</context-param>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
servlet程序
package com.study.service;
import javax.servlet.ServletConfig;
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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("-----执行 GET 方法----");
ServletConfig servletConfig = getServletConfig();
ServletContext servletContext = servletConfig.getServletContext();
String username = servletContext.getInitParameter("username");
String password = servletContext.getInitParameter("password");
System.out.println("context-param的值:"+username+" "+password);
System.out.println("当前工程路径:"+servletContext.getContextPath());
/* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到 IDEA 代码的 web 目录 */
System.out.println("工程部署路径:"+servletContext.getRealPath("/"));
System.out.println("工程下 index.jsp路径为:"+servletContext.getRealPath("/index.jsp"));
}
}
存取数据
三、HttpServletRequest 类
3.1 作用
每次只要有请求进入 Tomcat 服务器, Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。
然后传递到 service 方法( doGet 和 doPost) 中给我们使用。我们可以通过HttpServletRequest对象,获取到所有请求的信息。
3.2常用方法
代码测试
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// i.getRequestURI() 获取请求的资源路径
System.out.println("URI => " + req.getRequestURI());
// ii.getRequestURL() 获取请求的统一资源定位符(绝对路径)
System.out.println("URL => " + req.getRequestURL());
// iii.getRemoteHost() 获取客户端的 ip 地址
System.out.println("客户端 ip 地址 => " + req.getRemoteHost());
// iv.getHeader() 获取请求头
System.out.println("请求头 User-Agent ==>> " + req.getHeader("User-Agent"));
// vii.getMethod() 获取请求的方式 GET 或 POST
System.out.println( "请求的方式 ==>> " + req.getMethod() );
}
}
获取请求参数
System.out.println("请求参数获取:"+req.getParameter("username")+" "+req.getParameter("pwd"));//输入框
System.out.println("爱好:"); //多选框
String[] hobbies = req.getParameterValues("hobby");
for (String temp:hobbies){
System.out.println(temp);
}
3.3 解决中文乱码
doGet 解决中文乱码
// 获取请求参数
String username = req.getParameter("username");
//1 先以 iso8859-1 进行编码
//2 再以 utf-8 进行解码
username = new String(username.getBytes("iso-8859-1"), "UTF-8");
doPost解决中文乱码
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 设置请求体的字符集为 UTF-8, 从而解决 post 请求的中文乱码问题
req.setCharacterEncoding("UTF-8");
System.out.println("-------------doPost------------");
// 获取请求参数
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));
}
3.4 请求的转发
请求转发是指, 服务器收到请求后, 从一个资源跳转到另一个资源的操作叫请求转发。
浏览器地址栏不变。
代码测试
servlet1 程序
package com.study.service;
import javax.servlet.RequestDispatcher;
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 Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("程序====01=====做一些在程序1中的事情:(共享Request域中的数据)");
System.out.println("获取参数");
System.out.println(req.getParameter("username"));
req.setAttribute("key","value:盖章");
System.out.println("=========请求转发======");
// 斜杠表示 : http://ip:port/工程名/ , 映射到 IDEA 代码的 web 目录
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
System.out.println("出发……");
requestDispatcher.forward(req,resp);
}
}
servlet2程序
package com.study.service;
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 Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("====servlet2程序====");
System.out.println("查看参数:"+req.getParameter("username")+" "+req.getAttribute("key"));
System.out.println("处理自己的业务");
}
}
3.5 base 标签
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--base 标签设置页面相对路径工作时参照的地址
href 属性就是参数的地址值
-->
<base href="http://localhost:8080/07_servlet/a/b/">
</head>
<body>
这是 a 下的 b 下的 c.html 页面<br/>
<a href="../../index.html">跳回首页</a><br/> <!--跳转时,参照base标签地址 -->
</body>
</html>
四、HttpServletResponse 类
4.1 作用
每次请求进来, Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。
HttpServletRequest 表示请求过来的信息, HttpServletResponse 表示所有响应的信息。
我们如果需要设置返回给客户端的信息, 都可以通过 HttpServletResponse 对象来进行设置
4.2 输出流
- 字节流 getOutputStream(); 常用于下载(传递二进制数据)
- 字符流 getWriter(); 常用于回传字符串(常用)
注意:两个输出流只能使用一个,不能同时使用,否则报错。
4.3 回传数据
回传数据 显示在 html 页面
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("sevlet 回传数据");
}
4.4 中文乱码
方法一
方法二
4.5 请求重定向
请求重定向, 是指客户端给服务器发请求, 然后服务器告诉客户端说。 我给你一些地址。 你去新地址访问。 叫请求重定向(因为之前的地址可能已经被废弃) 。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(302);
resp.setHeader("Location","http://localhost:8080/servletStudy/servlet2");
}
五、Web中的路径 和 斜杠 /
相对路径和绝对路径
斜杠的意义