Java Web(5)-Servlet详解(下)
一、HttpServletRequest 类
1. HttpServletRequest 类作用?
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用,可以通过 HttpServletRequest 对象,获取到所有请求的 信息
2. HttpServletRequest 类的常用方法
- getRequestURI() 获取请求的资源路径
- getRequestURL() 获取请求的统一资源定位符(绝对路径)
- getRemoteHost() 获取客户端的 ip 地址
- getHeader() 获取请求头
- getParameter() 获取请求的参数
- getParameterValues() 获取请求的参数(多个值的时候使用)
- getMethod() 获取请求的方式 GET 或 POST
- setAttribute(key, value); 设置域数据
- getAttribute(key); 获取域数据
- getRequestDispatcher() 获取请求转发对象
具体如下:
首先把环境建好,配置好web.xml ,然后在类中
package com.md.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author MD
* @create 2020-07-25 8:18
*/
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(req.getRequestURI());// /04_Servlet/requestAPIServlet
System.out.println(req.getRequestURL());
//http://localhost:8080/04_Servlet/requestAPIServlet
System.out.println(req.getRemoteHost());//127.0.0.1
System.out.println(req.getHeader("User-Agent"));//Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
System.out.println(req.getMethod());//GET
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
对应的web.xml
<servlet>
<servlet-name>RequestAPIServlet</servlet-name>
<servlet-class>com.md.servlet.RequestAPIServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestAPIServlet</servlet-name>
<url-pattern>/requestAPIServlet</url-pattern>
</servlet-mapping>
3. 获取请求参数
首先在web下面建立html文件,如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/parameterServlet" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="python">Python
<input type="submit">
</form>
</body>
</html>
然后是对应的java代码,以及配置的web.xml(和上面的类似)
/**
* @author MD
* @create 2020-07-25 8:31
*/
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("------------doGet--------------");
// 获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
// String hobby = req.getParameter("hobby");
// 当有多个值的时候
String [] hobby = req.getParameterValues("hobby");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
System.out.println("爱好:"+ Arrays.asList(hobby));
}
}
4. 中文乱码
使用post请求的时候,如果用户名输入的是中文,则会出现中文乱码的情况,所以需要这样设置
public class ParameterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 在post的时候注意设置字符集,要不中文乱码
// 只有在获取请求参数调用之前使用才有效
req.setCharacterEncoding("UTF-8");
System.out.println("------------doPost--------------");
// 获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
// String hobby = req.getParameter("hobby");
// 当有多个值的时候
String [] hobby = req.getParameterValues("hobby");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
System.out.println("爱好:"+ Arrays.asList(hobby));
}
}
5. 请求转发
什么是请求的转发?
请求转发是指服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发
请求转发的特点:
- 浏览器地址栏没有改变
- 一次请求
- 共享Request域中的数据
- 可以转发到WEB-INF目录下
- 不可以访问工程以外的资源
例子如下:通过访问Servlet1然后转发到Servlet2去
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// http://localhost:8080/04_Servlet/servlet1?username=abc
// 1. 获取请求的参数
String username = req.getParameter("username");
System.out.println("在Servlet1中获取到的请求参数:"+username);
// 在Servlet1中获取到的请求参数:abc
// 2. 把获取到的数据传递,也可以自定义参数传递
// req.setAttribute("username" , username);
req.setAttribute("key","我来自Servlet1");
// 3. 转发
// 地址必须以 /开头 ,这个地址也是在web.xml中配置对应的你要去的
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
requestDispatcher.forward(req,resp);
// 或者可以直接这样
req.getRequestDispatcher("/servlet2").forward(req,resp);
}
}
对应的web.xml就不展示了,都类似
/**
* @author MD
* @create 2020-07-25 8:57
*/
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取请求的参数
String username = req.getParameter("username");
System.out.println("在Servlet2中获取到的请求参数:"+username);//在Servlet2中获取到的请求参数:abc
// 2. 查看从Servlet1中传递的参数
Object key = req.getAttribute("key");
System.out.println("Servlet1中传来的参数:"+key);//Servlet1中传来的参数:我来自Servlet1
// 3. 处理自己的业务
System.out.println("正在处理Servlet2的业务");//正在处理Servlet2的业务
}
}
6. base标签
所以在html文件中,跳转的时候若使用相对路径,指定相对的那个路径
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
base标签设置页面相对路径工作时参照的地址
href 属性就是参数的地址值
-->
<!--<base href="http://localhost:8080/04_Servlet/a/b/c.html">-->
<!--
也可以这样,但最后的斜杠不能省略
-->
<base href="http://localhost:8080/04_Servlet/a/b/">
</head>
<body>
这是a目录下的b目录下的c.html页面
<a href="../../index.html">跳到首页</a>
<!--通过定义了base,这个就相当于那个地址的上上层
http://localhost:8080/04_Servlet/index.html
-->
</body>
</html>
开发中尽量使用绝对路径,实在不行就使用base+相对路径
7. web中 / 斜杠的不同意义
在web中 / 是一种绝对路径
-
/ 斜杠被浏览器解析,得到的地址就是 http://ip:port
<a href="/">斜杠</a>
-
/ 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径
<url-pattern>/servlet1</url-pattern>
- servletContext.getRealPath(“/”);
- request.getRequestDispatcher(“/”);
-
特殊情况: response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到 http://ip:port/
二、HttpServletResponse 类
1. HttpServletResponse 类的作用
HttpServletResponse 类和 HttpServletRequest 类一样。
每次请求进来,Tomcat 服务器都会创建一个 Response 对象传 递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,
我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置
2. 两个输出流
字符流 | getWriter() | 用于传字符串(常用) |
---|---|---|
字节流 | getOutputStream() | 用于下载(传递二进制数据) |
3. 如何往客户端回传数据
首先还是先建立一个servlet,配置对应的web.xml
注意中文的乱码情况
package com.md.servlet;
/**
* @author MD
* @create 2020-07-25 9:57
*/
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println(resp.getCharacterEncoding());//ISO-8859-1
//
// // 设置服务器字符集为
// resp.setCharacterEncoding("UTF-8");
// // 此时若浏览器没有使用UTF-8中文还是乱码,这个时候需要
// // 通过设置响应头,使得浏览器也使用UTF-8字符集
// resp.setHeader("Content-Type","text/html; charset=UTF-8");
// 或者直接可以这样写,自动设置服务器字符集和浏览器响应头
// 方法一定要流获取之前先调用,通常放在最上面就行
resp.setContentType("text/html; charset=UTF-8");
// 需求:往客户端回传字符串数据
PrintWriter writer = resp.getWriter();
writer.write("response");
writer.write("越过山丘,");
}
}
4. 请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求 重定向(因为之前的地址可能已经被废弃)
请求重定向的特点:
- 浏览器的地址会发生改变
- 两次请求
- 不能共享Request域中的数据
- 不能访问WEB-INF下的资源
- 可以访问工程外的资源
例子如下:访问Response1重定向到Response2
/**
* @author MD
* @create 2020-07-25 10:15
*/
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Response 1 ");
// // 设置响应状态码,表示重定向
// resp.setStatus(302);
//
// // 设置响应头,说明新的地址,和web.xml里的要对应
// resp.setHeader("Location","http://localhost:8080/04_Servlet/response2");
// 推荐使用
resp.sendRedirect("http://localhost:8080/04_Servlet/response2");
}
}
//-----------------------------------
public class Response2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Response 2 ");
resp.getWriter().write("Response2 result !");
}
}
对应的web.xml
<servlet>
<servlet-name>Response1</servlet-name>
<servlet-class>com.md.servlet.Response1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Response1</servlet-name>
<url-pattern>/response1</url-pattern>
</servlet-mapping>
<!---->
<servlet>
<servlet-name>Response2</servlet-name>
<servlet-class>com.md.servlet.Response2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Response2</servlet-name>
<url-pattern>/response2</url-pattern>
</servlet-mapping>
-------------------------------------------
你闻讯而来,我大喜过望,我在这等你,你又在哪呢?喜欢的话加一个“关注”呗!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!