1、服务器响应流程:
1)服务器收到请求,为这个请求开辟一个新的线程。
2)创建request对象,封装请求数据 (request作为请求数据的载体)
3)创建response对象 用来与客户端连接,向客户端发送响应。
4)调用Servlet中的service()方法传递这两个参数
使用request获取请求数据
使用response完成响应。
插图:
2、request:封装客户端请求数据
请求协议中的数据都可以通过request对象获取
2.1 request获取获取请求头方法:
1)String getHeader(String name);单值头
2)int getIntHeader(String name);int单值头
3)long getDateHeader(String name);long单值头
4)Enumeration<String> getHeader(String name);多值请求头
获取请求头案例:通过UserAgent识别用户浏览器类型
//获取客户端的IP地址
String addr = request.getRemoteAddr();
System.out.println("IP"+ addr);
//获取请求方式
System.out.println("请求方式:"+ request.getMethod());
//获取名为 User-Agent 的请求头 (用户系统,浏览器信息等)
String useragent = request.getHeader("User-Agent");
System.out.println(useragent);
2.2 request获取url及参数的方法
http://localhost:8080/day10/AServlet?username=xxx&password=yyy
1)获取协议:String getScheme(); --- http
2)获取服务器名: String getServerName(); --- localhost
3)获取服务器端口: String getServerPort(); --- 8080
4)获取项目名: String getContextPath(); --- /day10
5)获取Servlet路径: String getServletPath(); --- /AServlet
6)获取参数部分: String getQueryString();---问号后面的部分 username=xxx&password=yyy
7)获取请求URI: String getRequestURI(); --- 项目名+路径 /day10/AServlet
8)获取请求URL: String getRequestURL();--- 不包含参数的整个路径 http://localhost:8080/day10/AServlet
获取url及参数的方法案例:防盗链
原理:使用ragferer请求头,检测是否为可允许的链接,若不是,发送404.
//获取ragferer请求头
String referer = request.getHeader("referer");
System..out.println(referer);
//判断是否为允许访问链接
//如果不包含允许链接字段或为空,跳转到百度
if(referer == null || !referer.contains("localhost")){ //当referer=null,说明是从地址栏直接输入的
response.sendRedirect("http://www.baidu.com");
}else{
System.out.println("hello");
}
3、request获取请求参数
请求参数由客户端发送给服务器
参数有可能在请求体中(POST),也有可能在IRL之后(GET),参数可以一对一,也可以一对多
3.1 request获取请求参数的方法
1)获取指定名称参数值,单值
String getParameter(String name)
2)获取指定名称的请求参数值 多值
String[] getParameterValues(String name)
3)获取所有请求参数,key为参数名 value为参数值
Map<String,String[]> getParameterMap()
4)获取所有请求参数名称
Enumeration<String> getParameterNames()
3.2 案例:获取HTML表单中提交的参数
html代码:
<body>
<a href="/day10_2/AServlet?xxx=XXX&yyy=YYY"> 链接地址</a>
<hr/>
<form action="/day10_2/AServlet" method="post2018/7/30">
用户名:<input type="text" name = "username" />
密码:<input type="password" name = "password" />
爱好:<input type="checkbox" name="hobby" value="est"/>吃饭
<input type="checkbox" name="hobby" value="sleep"/>睡觉
<input type="submit" value="提交"/>
</form>
</body>
java代码:
//得到get方法中的参数
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到get方法中的参数
System.out.println("GET:" + request.getParameter("xxx"));
System.out.println("GET:" + request.getParameter("yyy"));
}
//得到请求体中的参数
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到请求体中的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String[] hobby = request.getParameterValues("hobby");
System.out.println(username +","+ password +","+ Arrays.toString(hobby));
//获取所有请求参数名称
Enumeration<String> names = request.getParameterNames();
//遍历输出参数名2018/7/30
while(names.hasMoreElements()){
System.out.println(names.nextElement());
}
//获取所有参数,封装到Map中
Map<String,String[]> map = request.getParameterMap();
for (String name : map.keySet()) { //通过Map.set遍历key和value map.keyset()返回的是所有key
String[] value = map.get(name); //得到每个key对应的value
System.out.println(name +"="+ Arrays.toString(value));
}
}
4、请求转发和请求包含
一个请求中含有多个Servlet ,多个Servlet共享一个request。
方法:
1)request的getRequestDispatcher("/MyServlet")方法。参数为被调度的/Servlet路径
2)请求转发,由下一个Servlet完成响应体,当前Servlet只能设置响应头 //留头不留体
.forward(request,response);
3)请求包含 两个Servlet共同完成响应体。 //留头留体
.include(request,response);
请求转发实例:
//AServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("AServlet");
//设置响应头 响应头会被保留
response.setHeader("aaa","AAA");
//请求转发后,自身所作的响应体全被销毁
response.getWriter().print("hello AServlet");
//请求转发
request.getRequestDispatcher("/BServlet").forward(request, response);
}
//BServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("BServlet");
//响应
response.getWriter().print("hello BServlet");
}
注:做转发的Servlet不宜做响应,不能做过多的响应。
请求转发和重定向的四个区别:
1. 请求转发:一次请求一次响应。
重定向:两次请求,两次响应。
2. 请求转发地址栏不变
重定向转到后一个地址
3. 请求转发范围在本项目Servlet之间
重定向在项目之间,Servet之间都可以进行
4. 请求转发是服务器端行为。只需给出Servlet路径
重定向需要给URL
请求转发效率高
5、Servlet中的域
request、session、application,都有下面三个方法
void setAttribute(String name , Object value) //保存值
Object getAttribute(String name) //取值
void removeAttribute(String name) //删值