## 今日内容 :
1. Servlet
2. HTTP协议
3. Request
# Servlet 的体系结构:
1. Servlet --- 接口
两个实现类:
--- GenericServlet ------抽象类(继承此方法,只需要重写service方法)(不常用)
--- HttpServlet ------ 抽象
* GenericServlet: 将Servlet中的其他方法做了默认空实现,只将service方法作为抽象
* 将来在定义Servlet类时,可以继承GenericServlet,实现service方法即可。
* HttpServlet :对http协议的一种封装,简化操作
1. 定义继承HttpServlet
2. 重写doGet 和 doPost
# Servlet相关配置
1.urlpattern配置 :Servlet的访问路径
*(1) 一个Servlet可以定义多个访问路径(urlpattern)本身就是一个数组 : @WebServlet({"/d4","/d5"})
*(2) 路径定义规则 :
a. /xxx (常用)
b. /xxx/xxx :(多层路径) //@WebServlet("/user/demo4") @WebServlet("/user/*") —— * 代表通配符,写什么样的资源路径都可以访问到该资源,优先级最低。
3. *.do
# HTTP:
* 概念: Hyper Text Transfer Protocol 超文本传输协议
* 传输协议 : 定义了客户端和服务端通信时,发送数据的格式。
* 特点:
1. 基于TCP/IP的高级协议
2. 默认端口号 :80
http://www.baidu.com
3. 基于请求响应的: 一次请求,一次响应
4. 无状态的: 每次请求之间相互独立,不能交互数据
* 历史版本 :
1.0 : 每一次请求响应,都会建立一次新的连接
1.1 :复用连接
* 请求消息数据格式:
1. 请求行
请求方式 请求url 请求协议/版本
GET login.html http/1.1
* 请求方式:
* HTTP有7中请求方式,常用的有POST 和GET
* GET :
(1). 请求参数在请求行中,在url后边
(2)请求的url长度有限制
(3)不太安全
* POST:
(1)请求参数在请求体中
(2)请求的url长度没有限制
(3) 相对安全
2. 请求头
请求头名称 : 请求头值
* 常见的请求头:
(1)User-Agent : 浏览器告诉服务器,我访问你使用的浏览器版本信息。
* 可以在服务器端获取该头的信息,解决浏览器的兼容性问题。
(2) Referer : http://localhost/login.html
* 告诉服务器,我(当前请求)从哪里来?
* 作用:
a.防盗链
b. 统计工作
3. 请求空行
空行 :用于分割POST请求的请求头和请求体
4. 请求体 (正文)
* 封装POST 请求消息的请求参数
get 没有请求体,post有请求体
* 字符串格式:
GET login.html http/1.1(请求头)
Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding : gzip, deflate, br
Accept-Language : en,zh-CN;q=0.9,zh;q=0.
Host : localhost:8080
Upgrade-Insecure-Requests : 1
User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
username=zhangsan(请求体)
* 响应消息数据格式:
## Request:
前言:
(1. tomcat 服务器会根据请求的url中的资源路径,创建对应的ServletDemo1的对象。
(2. tomcat 服务器,会创建request 和 response 对象。request 对象中封装请求消息数据。
(3. tomcat 将request 和 response 两个对象传递给service 方法,并且调用service方法。
(4. 程序员可以通过request 对象获取请求消息数据,通过response 对象设置响应消息数据。
(5. 服务器在给浏览器做出响应前,会从response对象中拿出程序员设置的响应消息数据。
1. request 对象和 response对象的原理:
(1)request 和 response 对象是由服务器创建的,我们来使用他们
(2)request 对象是用来获取请求消息的,response对象是用来设置响应消息的。
2. request 对象继承体系结构:
ServletRequest -- 接口
继承
HttpServletRequest -- 接口
实现
org.apache.catalina.connector.RequestFacade --类 (tomcat)
2. request 功能 :
(1)获取请求消息数据:
a. 获取请求行数据
* GET /day14/demo1?name=zhangsan HTTP/1.1
* 方法 :
(1. 获取请求方式 : GET
* String getMethod()
(2. 获取虚拟目录 :/day14
* String getContextPath()
(3. 获取Servlet路径:/demo1
* String getServletPath()
(4. 获取get方式的请求参数 : name=zhangsan
* String getQueryString()
(5. 获取请求的URI :/day14/demo1
* String getRequsetURI() : /day14/demo1 ----- 统一资源标识符
* StringBuffer getRequsetURL() : http://localhost/day14/demo1 ------ 统一资源定位符
(6. 获取协议版本 : HHTP/1.1
* String getProtocol()
(7. 获取客户机的ip地址 :
* String getRemoteAddr()
代码展示:
package com.zhulin.web.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Janson
* @version 1.0
* @date 2019/10/9 11:33
*/
/**
* 演示request对象获取请求行数据
*/
@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
(1. 获取请求方式 : GET
* String getMethod()
(2. 获取虚拟目录 :/day14
* String getContextPath()
(3. 获取Servlet路径:/demo1
* String getServletPath()
(4. 获取get方式的请求参数 : name=zhangsan
* String getQueryString()
(5. 获取请求的URI :/day14/demo1
* String getRequsetURI() : /day14/demo1
* StringBuffer getRequsetURL() : http://localhost/day14/demo1
(6. 获取协议版本 : HHTP/1.1
* String getProtocol()
(7. 获取客户机的ip地址 :
* String getRemoteAddr()
*/
//(1. 获取请求方式 : GET
String method = request.getMethod();
System.out.println(method);
//(2. 获取虚拟目录 :/day14
String contextPath = request.getContextPath();
System.out.println(contextPath);
//(3. 获取Servlet路径:/demo1
String servletPath = request.getServletPath();
System.out.println(servletPath);
//(4. 获取get方式的请求参数 : name=zhangsan
String queryString = request.getQueryString();
System.out.println(queryString);
//(5. 获取请求的URI :/day14/demo1
String requestURI = request.getRequestURI();
System.out.println(requestURI);
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURL);
//(6. 获取协议版本 : HHTP/1.1
String protocol = request.getProtocol();
System.out.println(protocol);
//(7. 获取客户机的ip地址 :
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
b. 获取请求头数据
* 方法:
* String getHeader(String name) : 通过请求头的名称获取请求头的值
* Enumeration<String> getHeadername():获取所有请求头的名称
代码展示:Enumeration<String> getHeadername()
package com.zhulin.web.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**
* @author Janson
* @version 1.0
* @date 2019/10/9 15:20
*/
@WebServlet("/requestDemo2")
public class RequestDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//演示获取请求头数据
//1. 获取所有的请求头名称
Enumeration<String> headerNames = request.getHeaderNames(); //迭代器功能
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
//根据指定name获取header的值
String value = request.getHeader(name);
System.out.println(name+"-----"+value);
}
}
}
代码展示:String getHeader(String name)
package com.zhulin.web.request;
import sun.management.Agent;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Source;
import java.io.IOException;
/**
* @author Janson
* @version 1.0
* @date 2019/10/9 20:20
*/
@WebServlet("/requestDemo3")
public class RequestDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String agent = req.getHeader("user-agent");
System.out.println(agent);
//判断agent的浏览器版本
if (agent.contains("Chrome")){
//谷歌浏览器
System.out.println("谷歌 ..");
}else if (agent.contains("Firefox")){
System.out.println("火狐 ...");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
c. 获取请求体数据:
* 请求体: 只有POST请求方式,才有请求体,在请求体中封装了POST请求的 请求参数
* 步骤:
1. 获取流对象
* BufferedReader getReader() : 获取字符输入流,只能操作字符数据。
* ServletInputStream getInputStream() : 获取字节输入流,可以操作所有类型的数据。
* 主要用于文件上传
2. 再从流对象中拿数据
代码展示:
package com.zhulin.web.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
/**
* @author Janson
* @version 1.0
* @date 2019/10/10 14:07
*/
@WebServlet("/requestDemo5")
public class RequestDemo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader reader = req.getReader();
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
(2)其他功能:
a. 获取请求参数通用方式 : 不论get 还是 post 请求方式 ,都可以使用下列方法来获取请求参数。
1. String getParament(String name); :根据参数名称获取参数值
2 . String[] getParameterValues(String name) : 根据参数名称获取参数值的数组
3. Enumration<String> getParameterNames() : 获取所有请求的参数名称
4. Map<String,String[]> getParameterMap() : 获取所有参数的map集合
* 中文乱码问题 :
* get方式:tomcat8已经解决啦
* post方式:会存在乱码
* 解决 : 在获取参数前,设置request 的编码 request.setCharacterEncoding("utf-8");
b. 请求转发:一种在服务器内部的资源跳转方式
* 步骤:
1. 通过request对象获取请求转发器对象,RequestDispatcher getRequestDispatcher(String path)
2. 使用RequestDispatcher 对象进行转发 : forward(ServletRequest request , ServletResponse response)
* 特点 :
1. 浏览器地址路径不发生变化,
2. 只能转发到服务器内部的资源中
3. 转发是一次请求
c. 共享数据:
* 域对象 : 一个有作用范围的对象,可以在范围内共享数据
* request域 : 代表一次请求的范围,一般用于请求转发的多个资源中共享数据
* 方法 :
1. void setAttribute(String name,Object obj): 存储数据
2. Object getAttribute(String name): 通过键获取值
3. void removeAttribute(String name): 通过键移除键值对
d. 获取ServletContext :
* ServletContext getServletContext()
a代码展示:
package com.zhulin.web.request;
import jdk.internal.org.objectweb.asm.tree.analysis.Value;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @author Janson
* @version 1.0
* @date 2019/10/10 14:07
*/
@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//get获取请求参数
/* String username = req.getParameter("username");
System.out.println("get");
System.out.println(username);*/
this.doPost(req,resp); //简化代码,只写get或post中的一个,另一个在其中调用即可
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//post获取请求参数
String username = req.getParameter("username");
//System.out.println("post");
//System.out.println(username);
// 根据参数名称获取参数值的数组
String[] hobbies = req.getParameterValues("hobby");
/*for (String hobby : hobbies){
System.out.println(hobby);
}*/
//获取所有请求的参数名称
/* Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
System.out.println(name);
String value = req.getParameter(name);
System.out.println(value);
System.out.println("---------------");
}*/
//获取所有参数的map集合
Map<String, String[]> parameterMap = req.getParameterMap();
//遍历
Set<String> keySet = parameterMap.keySet();
for (String name : keySet){
String[] values = parameterMap.get(name);
System.out.println(name);
for (String value : values){
System.out.println(value);
}
System.out.println("-----下一个-----");
}
//迭代器
/* Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()){
String name = iterator.next();
System.out.println(name);
String value = req.getParameter(name);
System.out.println(value);
System.out.println("--------下一个");
}*/
}
}
b.c代码展示:
package com.zhulin.web.request;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**
* @author Janson
* @version 1.0
* @date 2019/10/10 14:07
*/
@WebServlet("/requestDemo7")
public class RequestDemo7 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp); //此处千万不要忘记哦,否则就出现无法输出数据情况啦
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo7被访问啦....");
//转发到demo8资源
/*RequestDispatcher requestDispatcher = req.getRequestDispatcher("/requestDemo8");
requestDispatcher.forward(req,resp);*/
//存储资源到域中
req.setAttribute("msg","hello");
//链式编程简化代码
req.getRequestDispatcher("/requestDemo8").forward(req,resp);
}
}
package com.zhulin.web.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**
* @author Janson
* @version 1.0
* @date 2019/10/10 14:07
*/
@WebServlet("/requestDemo8")
public class RequestDemo8 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp); //此处千万不要忘记哦,否则就出现无法输出数据情况啦
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo8被访问啦.....");
//获取数据
Object msg = req.getAttribute("msg");
System.out.println(msg);
}
}