package com.atguigu.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @author WHT
* @create 2021-06-14 13:45
*/
/**
* service 方法是专门用来处理请求和响应的。
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws 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() {
}
}
<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>HelloServletservlet-name>
<servlet-class>com.atguigu.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
web-app>
执行 Servlet 构造器方法 。
执行 init 初始化方法。
第一、二步,是在第一次访问,的时候创建 Servlet 程序会调用。
执行 service 方法。
第三步,每次访问都会调用。
执行 destroy 销毁方法。
第四步,在 web 工程停止的时候调用。
package com.atguigu.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* @author WHT
* @create 2021-06-14 13:45
*/
/**
* service 方法是专门用来处理请求和响应的。
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println("1 构造器方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3 service === Hello Servlet!"); // (需要自己写的地方)
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4 . destroy销毁方法");
}
}
1 构造器方法
2 init初始化方法
3 service === Hello Servlet!
3 service === Hello Servlet!
3 service === Hello Servlet!
3 service === Hello Servlet!
3 service === Hello Servlet!
3 service === Hello Servlet!
3 service === Hello Servlet!
D:\java\tomcat\apache-tomcat-8.0.50\bin\catalina.bat stop
Using CATALINA_BASE: "C:\Users\94435\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Tomcat_8_0_50_JavaWeb_2"
Using CATALINA_HOME: "D:\java\tomcat\apache-tomcat-8.0.50"
Using CATALINA_TMPDIR: "D:\java\tomcat\apache-tomcat-8.0.50\temp"
Using JRE_HOME: "D:\java\jdk-11.0.11"
Using CLASSPATH: "D:\java\tomcat\apache-tomcat-8.0.50\bin\bootstrap.jar;D:\java\tomcat\apache-tomcat-8.0.50\bin\tomcat-juli.jar"
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
14-Jun-2021 17:57:00.526 信息 [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
14-Jun-2021 17:57:00.527 信息 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-apr-8080"]
14-Jun-2021 17:57:00.587 信息 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-apr-8009"]
4 . destroy销毁方法
14-Jun-2021 17:57:00.651 信息 [main] org.apache.catalina.core.StandardService.stopInternal Stopping service Catalina
14-Jun-2021 17:57:00.678 信息 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-apr-8080"]
14-Jun-2021 17:57:00.741 信息 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-apr-8009"]
14-Jun-2021 17:57:00.797 信息 [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-apr-8080"]
14-Jun-2021 17:57:00.798 信息 [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-apr-8009"]
Disconnected from server
package com.atguigu.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author WHT
* @create 2021-06-14 13:45
*/
/**
* service 方法是专门用来处理请求和响应的。
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println("1 构造器方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3 service === Hello Servlet!");
// 类型转换(因为它有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取请求的方式
String method = httpServletRequest.getMethod();
if (method.equals("GET")) {
doGet();
} else if (method.equals("POST")) {
doPost();
}
}
/**
* 做get请求的操作
*/
public void doGet(){
System.out.println("get请求1");
System.out.println("get请求2");
}
/**
* 做post请求的操作
*/
public void doPost(){
System.out.println("post请求1");
System.out.println("post请求2");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4 . destroy销毁方法");
}
}
package com.atguigu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author WHT
* @create 2021-06-14 20:47
*/
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的 doGet 方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 的 doPost 方法");
}
}
package com.atguigu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author WHT
* @create 2021-06-14 21:09
*/
public class HelloServlet3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet3 的 doPost 方法");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("HelloServlet2 的 doGet 方法");
}
}
ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。
Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。
Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对 象。
<servlet>
<servlet-name>HelloServletservlet-name>
<servlet-class>com.atguigu.servlet.HelloServletservlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>rootparam-value>
init-param>
<init-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql://localhost:3306/testparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
// 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());
}
什么是域对象?
域对象,是可以像 Map 一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围,整个 web 工程。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1、获取web.xml中配置的上下文参数context-param
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("context-param参数username的值是:" + username);
System.out.println("context-param参数password的值是:" + context.getInitParameter("password"));
// 2、获取当前的工程路径,格式: /工程路径
System.out.println( "当前工程路径:" + context.getContextPath() );
// 3、获取工程部署后在服务器硬盘上的绝对路径
/**
* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到IDEA代码的web目录
*/
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:" + context.getRealPath("/css"));
System.out.println("工程下imgs目录1.jpg的绝对路径是:" + context.getRealPath("/imgs/1.jpg"));
}
<context-param>
<param-name>usernameparam-name>
<param-value>contextparam-value>
context-param>
<context-param>
<param-name>passwordparam-name>
<param-value>rootparam-value>
context-param>
public class ContextServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = getServletContext();
System.out.println(context);
System.out.println("保存之前: Context1 获取 key1的值是:"+ context.getAttribute("key1"));
context.setAttribute("key1", "value1");
System.out.println("Context1 中获取域数据key1的值是:"+ context.getAttribute("key1"));
}
}
public class ContextServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println(context);
System.out.println("Context2 中获取域数据key1的值是:"+ context.getAttribute("key1"));
}
}
什么是协议? —— 协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
所谓 HTTP 协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。
HTTP 协议中的数据又叫报文。
客户端给服务器发送数据叫请求。
服务器给客户端回传数据叫响应。
请求又分为 GET 请求,和 POST 请求两种。
Accept:表示客户端可以接收的数据类型。
Accpet-Languege:表示客户端可以接收的语言类型。
User-Agent:表示客户端浏览器的信息。
Host:表示请求时的服务器 ip 和端口号。
GET 请求有哪些:
POST 请求有哪些:
200 —— 表示请求成功。
302 —— 表示请求重定向。
404 —— 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)。
500 —— 表示服务器已经收到请求,但是服务器内部错误(代码错误)。
MIME 是 HTTP 协议中数据类型。
MIME 的英文全称是"Multipurpose Internet Mail Extensions" 多功能 Internet 邮件扩充服务。MIME 类型的格式是“大类型/小 类型”,并与某一种文件的扩展名相对应。
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。
public class RequestAPIServlet 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地址
/**
* 在IDEA中,使用localhost访问时,得到的客户端 ip 地址是 ===>>> 127.0.0.1
* 在IDEA中,使用127.0.0.1访问时,得到的客户端 ip 地址是 ===>>> 127.0.0.1
* 在IDEA中,使用 真实ip 访问时,得到的客户端 ip 地址是 ===>>> 真实的客户端 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() );
}
}
<body>
<form action="http://localhost:8080/07_servlet/parameterServlet" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
form>
body>
package com.atguigu.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.util.Arrays;
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("-------------doGet------------");
// 获取请求参数
String username = req.getParameter("username");
//1 先以iso8859-1进行编码
//2 再以utf-8进行解码
username = new String(username.getBytes("iso-8859-1"), "UTF-8");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
System.out.println("兴趣爱好:" + Arrays.asList(hobby));
}
@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));
}
}
什么是请求的转发? ——
请求转发是指,服务器收到请求后,从一个资源跳转到另一个资源的操作叫请求转发。
package com.atguigu.servlet;
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 {
// 获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料):" + username);
// 给材料 盖一个章,并传递到Servlet2(柜台 2)去查看
req.setAttribute("key1","柜台1的章");
// 问路:Servlet2(柜台 2)怎么走
/**
* 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA代码的web目录
*
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
// RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");
// 走向Sevlet2(柜台 2)
requestDispatcher.forward(req,resp);
}
}
ackage com.atguigu.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 Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求的参数(办事的材料)查看
String username = req.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料):" + username);
// 查看 柜台1 是否有盖章
Object key1 = req.getAttribute("key1");
System.out.println("柜台1是否有章:" + key1);
// 处理自己的业务
System.out.println("Servlet2 处理自己的业务 ");
}
}
DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base href="http://localhost:8080/07_servlet/a/b/">
head>
<body>
这是a下的b下的c.html页面<br/>
<a href="../../index.html">跳回首页a><br/>
body>
html>
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传 递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息。
我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置。
要求 : 往客户端回传 字符串 数据。
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 要求 : 往客户端回传 字符串 数据。
PrintWriter writer = resp.getWriter();
writer.write("response's content!!!");
}
}
解决响应中文乱码方案一(不推荐使用):
// 设置服务器字符集为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");
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说,我给你一些地址,你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)。
请求重定向的第一种方案:
// 设置响应状态码 302 ,表示重定向,(已搬迁)
resp.setStatus(302);
// 设置响应头,说明 新的地址在哪里
resp.setHeader("Location", "http://localhost:8080");
请求重定向的第二种方案(推荐使用):
resp.sendRedirect("http://localhost:8080");