目录
一、Request(请求)
1.作用
2.继承体系
3.获取请求数据
(1)请求行
(2)请求头
(3)请求体(POST)
(5)Request通用方式获取请求参数
4.Servlet模板
5.中文数据乱码解决
6.请求转发
二、Response(响应)
1.作用
2.继承体系
3.设置响应数据
(1)响应行
(2)响应头
(3)响应体
4.重定向
5.响应字符数据
6.响应字节数据
三、杂项问题
1.路径问题
2.插件推荐
一、Request(请求)
1.作用
获取请求数据
2.继承体系
-
Tomcat需要解析请求数据,封装为request对象并且创建request对象传递到service方法中
-
要使用request对象,可查阅JavaEE API文档的HttpServletRequest接口
3.获取请求数据
(1)请求行
方法名 | 说明 |
---|---|
String getMethod() | 获取请求方式:GET/POST... |
String getContextPath() | 动态获取虚拟目录(项目访问路径):/request-demo |
StringBuffer getRequestURL() | 动态获取URL(统一资源定位符):http://localhost:8080/request-demo/req1 |
String getRequestURl() | 动态获取URI(统一资源标识符): /request-demo/req1 |
String getQueryString() | 获取请求参数(GET方式):username=zhangsan&password=123 |
//测试网址:http://localhost:8080/tomcat_demo_war/request?username=zhangsan&password=123@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//final String reqMethod = req.getMethod();final String contextPath = req.getContextPath();final StringBuffer requestURL = req.getRequestURL();final String requestURI = req.getRequestURI();//username=zhangsan&password=123final String queryString = req.getQueryString();System.out.println(reqMethod);System.out.println(contextPath);System.out.println(requestURL);System.out.println(requestURI);System.out.println(queryString);}
结果:
(2)请求头
方法名 | 说明 |
---|---|
String getHeader(String name) | 根据请求头名称获取值 |
(3)请求体(POST)
方法名 | 说明 |
---|---|
ServletInputStream getInputStream() | 获取字节输入流 |
BufferedReader getReader() | 获取字符输入流 |
<form action="/request02" method="post"><!--确保表单内容有name属性!--><label><input type="text" placeholder="请输入用户名" name="username"><br></label><label><input type="password" placeholder="请输入密码" name="password"><br></label><input type="submit"></form>
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//System.out.println("req对象:" + req);//此流不需要自己手动关闭,在request对象被销毁的时候,该流会自动关闭final BufferedReader reader = req.getReader();final String s = reader.readLine();System.out.println(s);
}
(5)Request通用方式获取请求参数
方法名 | 说明 |
---|---|
Map< String,String[]> getParameter() | 获取所有参数Map集合 |
String[] getParameterValues(String name) | 根据名称获取参数值/数组 |
String getParameter(String name) | 根据名称获取参数值(单个值) |
html
<form action="/request03" method="get">
<!--确保表单内容有name属性!--><label><input type="text" placeholder="请输入用户名" name="username"><br></label><label><input type="password" placeholder="请输入密码" name="password"><br></label><label><input type="checkbox" name="hobby" value="run"></label>跑<label><input type="checkbox" name="hobby" value="jump"></label>跳<label><input type="checkbox" name="hobby" value="eat"></label>吃<input type="submit"></form>
java:
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {final Map<String, String[]> reqParameterMap = req.getParameterMap();reqParameterMap.forEach((k,v) -> {System.out.println(k+":"+ Arrays.toString(v));});
final String[] hobby = req.getParameterValues("hobby");System.out.println(Arrays.toString(hobby));//只会获取数组中的第一个数据final String hobby1 = req.getParameter("hobby");System.out.println(hobby1);}
@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {final Map<String, String[]> reqParameterMap = req.getParameterMap();reqParameterMap.forEach((k,v) -> {System.out.println(k+":"+ Arrays.toString(v));});
final String[] hobby = req.getParameterValues("hobby");System.out.println(Arrays.toString(hobby));//只会获取数组中的第一个数据final String hobby1 = req.getParameter("hobby");System.out.println(hobby1);}
优化重复代码:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {final Map<String, String[]> reqParameterMap = req.getParameterMap();reqParameterMap.forEach((k,v) -> {System.out.println(k+":"+ Arrays.toString(v));});
final String[] hobby = req.getParameterValues("hobby");System.out.println(Arrays.toString(hobby));//只会获取数组中的第一个数据final String hobby1 = req.getParameter("hobby");System.out.println(hobby1);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req,resp);
}
4.Servlet模板
如果还觉得不够省事,可以修改模板
5.中文数据乱码解决
如果是Tomcat8及以上的版本,恭喜这个问题可以跳过~
预防万一解决方式也写一下
POST:
方法名 | 说明 |
---|---|
setCharacterEncoding("UTF-8"); | 设置字符流编码格式 |
GET:
URL编码
-
将字符串按照编码方式转为二进制
-
每个字节转为2个16进制数并在前边加上%
Tomcat默认编码:ISO-8859-1
解决方式:该方法通用
-
将接收数据先转成字节数据
-
之后再解码变成汉字
public class UrlDemo {public static void main(String[] args) throws UnsupportedEncodingException {//URL编码//浏览器String s = "张三";final String encode = URLEncoder.encode(s,"utf-8");System.out.println(encode);
//URL解码//Tomcat//Tomcat8以下默认使用的是ISO-8859-1final String decode = URLDecoder.decode(encode, "ISO-8859-1");System.out.println(decode);
//转为字节数据,编码final byte[] bytes = decode.getBytes(StandardCharsets.ISO_8859_1);for (byte aByte : bytes) {System.out.print(aByte+" ");}System.out.println();
//字节数组转字符串,解码final String s1 = new String(bytes, StandardCharsets.UTF_8);System.out.println(s1);}
}
6.请求转发
请求转发(forward):一种在服务器内部的资源跳转方式
实现方式:
//写在资源A
req.getRequestDispatcher("资源B路径").forward(req,resp);
请求转发资源间共享数据:使用Request对象
方法名 | 说明 |
---|---|
void setAttribute(String name, Object o) | 存储数据到 request域中 |
Object getAttribute(String name) | 根据 key,获取值 |
void removeAttribute(String name) | 根据 key,删除该键值对 |
特点:
-
浏览器地址栏路径不发生变化
-
只能转发到当前服务器的内部资源
-
一次请求,可以在转发的资源间使用request共享数据
二、Response(响应)
1.作用
设置响应数据
2.继承体系
3.设置响应数据
(1)响应行
方法名 | 说明 |
---|---|
void setStatus(int sc) | 设置响应状态码 |
(2)响应头
方法名 | 说明 |
---|---|
void setHeader(String name,String value) | 设置响应头键值对 |
(3)响应体
方法名 | 说明 |
---|---|
PrintWriter getWriter() | 获取字符输出流 |
ServletOutputStream getOutputStream() | 获取字节输出流 |
4.重定向
重定向(Redirect):一种资源跳转方式
System.out.println("resp01");
response.setStatus(302);
//不区分大小写
response.setHeader("Location","/response02");
//简化
response.sendRedirect("/response02");
特点:
-
浏览器地址栏路径发生变化
-
可以重定向到任意位置的资源(服务器内部、外部均可)
-
两次请求,不能在多个资源使用request共享数据
5.响应字符数据
//中文乱码解决
//原因:通过Response获取的字符输出流默认编码:ISO-8859-1
response.setContentType("text/html;charset=utf-8");
//解析html标签
response.setHeader("content-type","text/html");
//流不需要手动关闭,随着响应结束,response对象销毁,由服务器关闭
final PrintWriter writer = response.getWriter();
writer.write("测试");
writer.write("ceshi");
writer.write("<h1>测试</h1>");
6.响应字节数据
//读取文件
FileInputStream fis = new FileInputStream("D:/新建文件夹 (2)/图片素材/13516761_0_final.png");
//获取response字节输出流
final ServletOutputStream os = response.getOutputStream();
//完成流的copy
final byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1){os.write(buffer,0,length);
}
fis.close();
IO工具类:
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>
//读取文件
FileInputStream fis = new FileInputStream("D:/新建文件夹 (2)/图片素材/13516761_0_final.png");
//获取response字节输出流
final ServletOutputStream os = response.getOutputStream();
IOUtils.copy(fis,os);
三、杂项问题
1.路径问题
浏览器使用:需要加虚拟目录(项目访问路径) 服务端使用:不需要加虚拟目录
动态获取虚拟目录:
final String contextPath = request.getContextPath();
System.out.println(contextPath);
//简化
response.sendRedirect(contextPath + "/response02");
2.插件推荐
File Path Autocomplete: