Servlet(二)
Servlet(二)
HttpServletRequest类
作用
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过HttpServletRequest对象,获取到所有请求的信息。
常用方法
-
getRequestURI()
获取请求的资源路径
-
getRequestURL()
获取请求的统一资源定位符(绝对路径)
-
getRemoteHost()
获取客户端的ip 地址
- 在IDEA中使用localhost访问时,得到的客户端ip地址是127.0.0.1
- 在IDEA中使用127.0.0.1访问时,得到的客户端ip地址是127.0.0.1
- 在IDEA中使用真实的ip访问时,得到的客户端ip地址是真实的ip地址
-
getHeader()
获取请求头
-
getParameter()
获取请求的参数
-
getParameterValues()
获取请求的参数(多个值的时候使用)
-
getMethod()
获取请求的方式GET或POST
-
setAttribute(key, value)
设置域数据
-
getAttribute(key)
获取域数据
-
getRequestDispatcher()
获取请求转发对象
代码实现
public class RequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// getRequestURI():获取请求的资源路径
System.out.println("URI:" + req.getRequestURI());
// getRequestURL():获取请求的统一资源定位符(绝对路径)
System.out.println("URL:" + req.getRequestURL());
// getRemoteHost():获取客户端的ip 地址
//在IDEA中使用localhost访问时,得到的客户端ip地址是127.0.0.1
System.out.println("ip:" + req.getRemoteHost());
// getHeader():获取请求头
System.out.println("请求头User-Agent的信息:" + req.getHeader("User-Agent"));
// getMethod():获取请求的方式GET或POST
System.out.println("请求的方式:" + req.getMethod());
}
}
获取请求的参数方法的使用
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//获取请求的参数(多个值的时候使用)
String[] hobbies = req.getParameterValues("hobby");
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
System.out.println("兴趣爱好:" + Arrays.asList(hobbies));
}
}
注意
-
get请求的中文乱码解决
// 获取请求参数 String username = req.getParameter("username"); //1 先以iso8859-1 进行编码 //2 再以utf-8 进行解码 username = new String(username.getBytes("iso-8859-1"), "UTF-8");
-
post请求时输入中文可能会出现乱码,需要设置请求体的字符集,在获取请求之前调用才有效
//设置请求体的字符集 req.setCharacterEncoding("UTF-8");
请求的转发
请求转发是指服务器收到请求后,从一个资源跳转到另一个服务器资源的操作叫请求转发。
过程
-
Servlet类中的过程:
- 获取请求的参数
- getParameter()方法
- 使用域数据给参数进行“盖章”
- setAttribute()方法
- 请求转发到Servlet2
- 请求转发必须要以斜杠打头,斜杠表示地址为http://ip:port/工程名/,映射到IDEA代码的web目录
- getRequestDispatcher(String s)方法
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
- “走向”Servlet2
- forward()方法
- 获取请求的参数
-
Servlet2类中的过程
- 获取请求的参数
- 查看Servlet1是否有“盖章”
- 域数据中的key一定要与Servlet中设定的相同
- 处理自己的业务
代码实现
Servlet1
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中查看参数:" + username);
//使用域数据给参数进行“盖章”
req.setAttribute("key","Servlet1");
//问路:Servlet2怎么走
/**
* 请求转发必须要以斜杠打头,斜杠表示地址为http://ip:port/工程名/,映射到IDEA代码的web目录
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
//走向Servlet2
requestDispatcher.forward(req,resp);
}
}
Servlet2
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中查看参数:" + username);
//查看Servlet1是否“盖章”
Object key = req.getAttribute("key");
System.out.println("Servlet1是否“盖章”:" + key);
//处理自己的业务
System.out.println("servlet2处理自己的业务");
}
}
运行结果
请求转发的特点
- 浏览器地址栏没有变化
- 是一次请求(虽然访问两个资源,但是只是一个请求)
- 共享request域中的数据
- 可以转发到WEB-INF目录下(正常情况下浏览器无法访问WEB-INF目录下文件,通过请求转发可以访问)
base标签
所有相对路径在工作时候都会参照当前浏览器地址栏中的地址进行跳转
base标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转
base标签一般写在title标签下面
相对路径和绝对路径
-
相对路径
- . 表示当前目录
- .. 表示上一级目录
- 资源名 表示当前目录/资源名
-
绝对路径
http://ip:port/工程路径/资源路径
web中 / 斜杠的不同意义
在web中 / 斜杠是一种绝对路径
- / 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
- / 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
- 特殊情况:response.sendRedirect(“/”); 把斜杠发送给浏览器解析。得到http://ip:port/
HttpServletResponse类
HttpServletResponse类和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response 对象传递给Servlet程序去使用。
HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置
两个输出流
字节流
getOutputStream():常用于下载(传递二进制数据)
字符流
getWriter():常用于回传字符串(常用)
特点
两个流同时只能使用一个。
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
回传数据
代码举例
public class ResponseIO extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(resp.getCharacterEncoding());
//设置服务器字符集为UTF-8
resp.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器也使用UTF-8字符集
resp.setHeader("Content-Type","text/html;charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("回传成功");
}
}
响应中文乱码问题
-
方法一
-
设置服务器字符集为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");
注意:此方法一定要在获取流对象之前调用才有效
请求重定向
请求重定向:客户端给服务器发请求,然后服务器告诉客户端我给你一些地址,你去新地址访问,叫请求重定向(因为之前的地址可能已经被废弃)
特点
- 浏览器地址栏会发生变化
- 两次请求
- 不共享Request域中的数据
- 不能访问WEB-INF下的资源
- 可以访问工程外的资源
请求重定向的方法
-
方法一
//设置响应状态码302,表示重定向 resp.setStatus(302); //设置响应头,说明新的地址 resp.setHeader("Location","http://localhost:8080/Servlet_02/Response2");
-
方法二(推荐使用)
resp.sendRedirect("https://www.baidu.com/");