一、 请求过程
1.浏览器发起请求
2.tomcat会根据请求url中的资源路径,创建对应的Servlet对象
3.tomcat服务器创建request对象和response对象,request对象中封装请求消息数据
4.tomcat将request和response两个对象传递给Servlet对象的Service()方法,并调用Service()
5.程序员通过request对象获取请求消息数据,通过response对象设置响应消息数据。
注意:request对象和response对象是由服务器创建的
二、HttpServletRequest类
a) HttpservletRequest类的作用
b) Request继承体系
ServletRequest(接口)
|
HttpServletRequest(子接口)
|
org.apache.catalina.connector.RequestFacade(Tomcat 实现的实现类)
c ) HttpServletRequest类常用方法
- getRequestURI() 获取请求的资源路径
- getRequestURL() 获取请求的统一资源定位符(绝对路径)
- getRemoteHost() 获取客户端的IP地址
- getParameter() 获取请求的参数
- getParametervalues() 获取请求的参数(多个值的时候使用)
- getMethod() 获取请求的方式(get\post)
- setAttribute(key,value) 设置域数据
- getAttribute(key) 获取域数据
- getRequestDispatcher() 获取请求转发对象
- getHeader() 获取请求头
- String getHeader(String name):通过请求头的名称获取请求头的值
- Enurmation getHeaderNames():获取所有请求头名称
Enurmation是个可迭代对象:
while(headerNames.hasMore()){
String name = headerNames.nextElement();
String value = request.getrHeader(name);
}
d)获取请求体数据
注意: 只有post请求方式才有请求体,请求体中封装了POST请求的请求参数
步骤:
1.获取流对象
BufferedReader getReader() 只能获取字符数据 有readLine()方法,按行读取
ServletInputStream getInputStream() 获取字节输入流
2.再从流对象中拿数据
BufferedReader br = request.getReader();
String line = null;
while((line = br.read())!= null){
System.out.println(line);
}
e) 获取请求参数通用方法
通用方法指的是get\post请求都可以用
1.String getParameter(String name) 根据请求参数名称获取参数值
2.String[] getParameterValues(String name):根据参数名称获取参数值的数组(复选框使用)
3.Enumeration<String> getParameterNames():获取所有请求的参数名称
4.Map<String,String[]> getParameterMap() 获取所有参数的k-v集合
f) 获取请求参数中文乱码问题
String username = request.getParameter("username");
System.out.println(username);
- 上述代码中,如果请求是get方式,那么不会有中文乱码问题;但是如果如果是post方式,就会报错!
解决方案:
即使用通用的获取请求参数的方法,对于post来说,第一步也是获取流,所以在获取请求参数之前,先设置流的编码方式,注意编码方式和HTML页面的编码方式保持一致。
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
System.out.println(username);
g) 请求转发
- 什么是请求转发?
服务器收到请求后,从一次资源跳转到另一个资源的操作
请求转发属于在服务器内部的资源跳转方式
- 请求转发的使用
步骤:
1.通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
2.使用RequestDispatcher对象来进行转发:
forward(ServletRequest request,ServletResponse response)
示例: demo08转发到demo09
@WebServlet("/demo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet08被访问了");
RequestDispatcher rd =req.getRequestDispatcher("/Demo09");
rd.forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
@WebServlet("/demo09")
public class ServletDemo09 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet09被访问了");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
}
- getRequestDispatcher(String path)的path必须以
/
开头;/
表示地址为:http://ip:port/工程名/,映射到IDEA代码的Web目录
- 请求转发的特点
- 浏览器地址路径不发生改变;也就是访问Servlet1,转发到Servlet2,但地址栏不会改变
- 请求转发访问不同的资源,但是始终是一次请求;
- 由于转发是一次请求,也就是说多个Servlet之间共享Request对象中的数据
- WEB-INF目录下的资源是直接无法访问的,但是通过请求转发可以访问
- 只能转发到当前服务器内部资源中
转发的时候,直接将要访问的资源放在了当前web目录下,所以无法访问web项目外部的资源;
h) base标签的作用
演示:
但是请求转发不能从c.html跳回来了
base标签相当于href的相对路径中的出发点;
注意:如果href的值是目录结尾,必须加上/
结尾,如果是资源就没事;