04-Request 与 Response
对应原始资料:
day06-Request+Response
一、HttpServletRequest
代表一次 HTTP 请求,由 Tomcat 创建并传入 Servlet。
1. 获取请求行 / 头 / 参数
java
// 请求行
req.getMethod(); // GET / POST
req.getRequestURI(); // /demo/hello
req.getRequestURL(); // http://localhost:8080/demo/hello
req.getQueryString(); // id=1&name=zs
req.getProtocol();
// 请求头
req.getHeader("User-Agent");
req.getHeaderNames();
// 请求参数(GET 的 query string 和 POST 的 body 都可用)
String name = req.getParameter("name");
String[] hobbies = req.getParameterValues("hobby");
Map<String, String[]> map = req.getParameterMap();2. 中文乱码问题
- GET:Tomcat 8+ 已自动处理 UTF-8。
- POST:必须手动设置:
java
req.setCharacterEncoding("UTF-8"); // 必须在 getParameter 之前- 响应:
resp.setContentType("text/html;charset=UTF-8");
3. 请求转发(forward)
java
req.setAttribute("msg", "hello");
req.getRequestDispatcher("/result.jsp").forward(req, resp);特点:
- 一次请求,地址栏不变。
- 转发的资源共享同一个 request。
- 只能转发到服务器内部资源。
4. BeanUtils 封装参数
java
User u = new User();
BeanUtils.populate(u, req.getParameterMap()); // 把 map 自动赋给对象属性二、HttpServletResponse
代表一次 HTTP 响应。
1. 输出内容
java
// 字符流(输出文本)
resp.setContentType("text/html;charset=UTF-8");
PrintWriter w = resp.getWriter();
w.write("<h1>hello</h1>");
// 字节流(输出二进制,如文件下载、图片)
ServletOutputStream os = resp.getOutputStream();2. 重定向(redirect)
java
resp.sendRedirect("/demo/index.html");特点:
- 两次请求,地址栏变化。
- 不共享 request 域。
- 可重定向到外部网站。
3. 转发 vs 重定向
| 维度 | 转发 forward | 重定向 redirect |
|---|---|---|
| 请求次数 | 1 | 2 |
| 地址栏 | 不变 | 变 |
| 域对象 | 共享 | 不共享 |
| 目标范围 | 服务器内 | 任意 URL |
三、文件下载
java
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String filename = "a.jpg";
String path = getServletContext().getRealPath("/img/" + filename);
FileInputStream fis = new FileInputStream(path);
// 设置响应头,告诉浏览器以下载方式打开
resp.setHeader("Content-Disposition", "attachment;filename=" + filename);
ServletOutputStream os = resp.getOutputStream();
byte[] buf = new byte[8192];
int len;
while ((len = fis.read(buf)) != -1) os.write(buf, 0, len);
fis.close();
}
}中文文件名乱码(IE/Chrome)
java
filename = URLEncoder.encode(filename, "UTF-8");四、文件上传
1. 前端
html
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>2. 后端(Servlet 3.0 注解)
java
@MultipartConfig
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws Exception {
req.setCharacterEncoding("UTF-8");
Part part = req.getPart("file");
String name = part.getSubmittedFileName();
part.write(getServletContext().getRealPath("/upload/") + name);
}
}五、JSON 响应
后端常用 Jackson 或 Fastjson 把对象转成 JSON 返回:
java
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
resp.setContentType("application/json;charset=UTF-8");
resp.getWriter().write(json);六、综合思路:原生 Servlet + Vue
- 前端 Vue + axios 调用
/api/user。 - 后端 Servlet 用
getPart/getParameter取参数。 - 业务层调用 JDBC。
- 用 Jackson 把结果转 JSON 写回。
- 前端 axios 拿到 JSON 后渲染。
这就是 SpringMVC 在背后做的事——Servlet 是底层引擎,框架帮你做了参数提取、JSON 转换、路由分发。
练习建议
- 用 Servlet 接收表单参数并输出到页面。
- 实现转发到 success.jsp,对比重定向。
- 实现图片下载(带中文文件名)。
- 用
@MultipartConfig实现文件上传,把文件保存到/upload。 - 用 Jackson 返回一个对象,前端用 axios 接收。