一、请求响应原理
1.请求响应流程图
2.服务器处理请求的流程:
服务器每次收到请求时,都会为这个请求开辟一个新的线程
服务器会把客户端的请求数据封装到request对象中,request就是请求数据的载体
服务器还会创建response对象,这个对象与客户端连接在一起,它可以用来向客户端发送响应
二、response
1.response-->HttpServletResponse
ServletResponse-->与协议无关的类型
HttpServletResponse-->与http协议相关的类型
2.HttpServletResponse: api
状态码:
sendError(int sc):发送错误状态码
sendError(int sc,String msg):发送错误状态码,还带一个错误信息
sendStatus(int sc):发送正确状态码
响应头:Content-Type,Refresh,Location等等
头就是一个键值对,可能存在一个头(一个名字,一个值),或(一个名字,多个值)
setHeader(String name,String value):适用于单值的响应头
addHeader(String name,String value):适用于多值的响应头
setIntHeader(String name,String value):适用于单值的int类型的响应头
addIntHeader(String name,String value):适用于多值的int类型的响应头
setDateHeader(String name,long value):适用于单值的毫秒类型的响应头
addDateHeader(String name,long value):适用于多值的毫秒类型的响应头
注意:<meta>标签可以代替响应头,<meta http-equip="Content-Type" content="text/html";charset="UTF-8">
响应体:通常是html,也可以是图片
response的两个流
ServletOutputStream:用来向客户端发送字节数据
PrintWriter:用来向客户端发送字符数据
注意:!!!两个流不能同时使用
重定向:设置302,设置Location,其中变化的只有Location,所以java提供了一个快捷方法完成重定向
sendRedirect(String location)方法
三、request
request:封装了客户端所有的请求数据,格式如下:
请求行
请求头
空行
请求体(Get没体)
1.获取常用信息
获取客户端IP,案例:封IP request.getRemoteAddr()
请求方式,request.getMethod(),可能是POST也可能是GET
2. 获取HTTP请求头
String getHeader(String name),适用于单值请求头
int getIntHeader(String name),适用于int类型单值请求头
long getDateHeader(String name),适用于单值毫秒类型请求头
Enumeration<String> getHeaders(String name),适用于多值请求头
案例:
通过User-Agent识别用户浏览器类型
防盗链:如果请求不是超过本站的超链接发出的,发送错误状态码404;Referer这个请求头,表示请求的来源
3.获取请求URL:
4.获取请求参数
请求参数是客户端发送给服务器的,有可能是在请求体中(Post),也可能是在URL之后(Get)
请求参数:有一个参数一个值的,也有一个参数多个值的
String getParameter(String name):单值的
String [] getParameterValues(String name):多值的
Enumeration<String> getParameterNames():所有请求参数名称
Map<String,String[]> getParameterMap():获取所有的请求参数,其中key为参数名,value为参数值
案例:超链接参数
案例:表单数据 javaweb__4 AServlet
5.请求转发和请求包含
注意:请求转发和请求包含是同一个请求
RequestDispatcher rd=request.getRequestDispatcher("/MyServlet");
//使用request获取RequestDispatcher,参数为Servlet的路径
请求转发:rd.forward(request,response);
请求包含:rd.include(request,response);
原理:有时一个Servlet需要多个Servlet协作才能完成,所以需要在一个Servelt调到另一个Servlet!!!
一个请求跨多个Servelt,需要使用转发和包含(重定向,两个请求)
请求转发:由下一个Servlet完成响应体,当前Servelt可以设置响应头(留头不留体)
请求包含:由两个Servlet共同来完成响应体!(都留)
无论是请求转发还是请求包含,都在一个请求范围内,使用同一个request和response
(浏览器url为前一个Servlet的路径,因为只存在一个请求)
6.请求转发和重定向的区别:
请求转发是一个请求一次响应,而重定向是两个请求两次响应
请求转发地址栏不变化,而重定向会显示后一个请求的地址
请求转发只能转发到本项目的其他Servlet,而重定向不止能重定向到本项目的其他Servlet,还能定向到其他Servlet
请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,即包含项目名
请求转发效率高,因为是一个请求!
需要地址栏发送变化,那么必须使用重定向
需要在下一个Servlet中获取request域中的数据,必须要使用转发
7.request域
Servlet中三大域:request\session\application都有以下三个方法:
void setAttribute(String name,Object value)
Object getAttribute(String name)
void removeAttribute(String name)
同一请求范围内使用request.setAttribute(),request.getAttribute()来传值,
前一个Servlet调用setAttribute保存值,后一个Servlet调用getAttribute获取值
四、编码
常见字符编码:iso-8859-1(不支持中文),gbk(系统默认编码,中国的国标码),utf-8(万国码,支持全世界的编码,所以使用这个)
1.响应编码
在使用response.getWriter()来向客户端发送字符数据时,如果之前没有设置编码,那么默认使用iso,所以中文一定乱码,
具体如下图:
2.请求编码
post请求中,需要request.setCharaacterEncoding("utf-8");再使用getParameter()来获取参数
get请求中,暂时未出现乱码,了解到tomcat9的默认编码格式是utf-8
3.URL编码
表单的类型:Content-Type:application-x-www-from-urlencoded,就是把中文转换成%后面跟随两位的16进制
为什么要用它:在客户端和服务端之间传递中文时需要把它转换成网络适合的方式
它不是字符编码
它是用在客户端和服务端之间传递参数的一种方式。
post请求默认就使用URL编码,tomcat会自动使用URL解码
URL编码:String username=URLEncoder.encode(username,"utf-8");
URL解码:String username=URLDecoder.decode(username,"utf-8");
最后我们需要把链接的中文参数,使用url来编码(html不能给出java代码,后期学jsp即可)
五、路径总结
1. web.xml中<url-pattern>路径(叫做Servlet路径)
要么以*开头,要么以/开头
2. 转发和包含路径
***建议使用***以"/"开头,相对当前项目路径,例如:http://localhost:8080/项目名
不以"/"开头,相对当前Servlet路径
3. 重定向路径(客户端路径)
***建议使用***以"/"开头,相对当前主机,例如http://localhost:8080/
不以"/"开头,相对页面所在路径
4. 页面中超链接和表单路径
与重定向相同,都是客户端路径,需要添加项目名<"/day1_1/AServlet">
5. ServletContext获取资源路径
相对项目目录,即index.jsp所在目录
6. ClassLoader获取资源路径
相对classes目录
Class获取资源路径
以"/"开头相对classes目录
不以"/"开头相对.class文件所在目录
注:文章中图片来源-->传智播客