Request&Response
- Request:获取请求数据
- Response:设置响应数据
一.Request对象
1.Request继承体系
- Tomcat需要解析请求数据,封装为requestx对象并且创建requestx对象传递到service方法中
- 使用request对象,查阅JavaEE API文档的HttpServletRequest接口
2.Request获取请求数据
2.1获取请求数据
- 请求数据分为3部分:
1.请求行:
GET /request-demo/req1?username=zhangsan HTTP/1.1
- String getMethod():获取请求方式:GET
- String getContextPath():获取虚拟目录(项目访问路径):/request-demo
- StringBuffer getRequestURL0:获取URL(统一资源定位符):http:/localhost:8080/request-demo/req1
- String getRequestURI():获取URI(统一资源标识符):/request-demo/req1
- String getQueryString() :获取请求参数(GET方式):username=zhangsan&password=123
2.请求头
User-Agent:Mozilla/5.0 Chrome/91.0.4472.106
- String getHeader(String name):根据请求头名称,获取值
3.请求体
username=superbaby&password=123
- ServletInputStream getlnputStream():获取字节输入流
- BufferedReader getReader(():获取字符输入流
2.2通用方式获取请求参数
- 请求参数获取方式
get方式:
String getQueryString()
post方式:
BufferedReader getReader()
思考:
GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码?
3.Request通用方式获取请求参数
- Map<String,String[]>getParameterMap():获取所有参数Map集合
- String[]getParameterValues(String name):根据名称获取参教值(数组)
- String getParameter(String name):根据名称获取参数值(单个值)
- 使用通用方式获取请求参数后,屏蔽了GET和POST的请求方式代码的不同,则代码可以定义为如下格式:
@WebServlet("/reqDemo3") public class RequestDemo3 extends HttpServlet{ @override protected void doGet(HttpServletRequest req,HttpServletResponse resp){ } @override protected void doPost(HttpServletRequest req,HttpServletResponse resp){ this.doGet(req,resp); } }
- 可以使用Servlet模板创建Servlet更高效
若是没有new Servlet选项
- 在pom.xml文里导入servlet得依赖
- 在File里的Project Structure找到Modules
- 点击Dependencies勾选servlet-api的选项
若想改变模板的格式
4.Request请求参数中文乱码
请求参数如果存在中文数据,则会乱码
//POST的乱码
//1.解决乱码:PoST的底层实现是getReader
request.setCharacterEncoding("UTF-8");//设置字符输入流的编码
//要先设置编码格式,否则后续仍然会中文乱码
//2.获取username
String username = request.getParameter("username");
System.out.println(username);
//GET的乱码
//1.GET,获取参数的方式:getQuerystring
//乱码原因:tomcat进行URL解码,默认的字符集IS0-8859-1
//1.1先对乱码数据进行编码:转为字节数组
username.getByte(StandardCharsets.IS0_8859_1);
//1.2字节数组解码
username = new String(bytes,StandardCharsets.ISO_8859_1)
//1.1和1.2可合为一行
username = new String(username.getBytes((StandardCharsets.ISO_8859_1),StandardCharsets.ISO_8859_1);
get的乱码原因
URL编码
1.将字符串按照编码方式转为二进制2.每个字节转为2个16进制数并在前边加上%
解决方案:
POST:设置输入流的编码
req.setCharacterEncoding("UTF-8");
通用方式(GET/POST):先编码,再解码
new String(username.getBytes("ISO-8859-1"),"UTF-8");
Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8
5.Request请求转发
请求转发(forward):一种在服务器内部的资源跳转方式
实现方式
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.Response设置响应数据功能介绍
响应数据分为3部分
1.响应行:
HTTP/1.1 200 OK
void setStatus(int sc):设置响应状态码
2.响应头:
Content-Type:text/html
void setHeader((String name,String value):设置响应头键值对
3.响应体:
<html><head>head><body></body></html>
PrintWriter getWriter():获取字符输出流
ServletOutputStream getQutputStream():获取字节输出流
2.Response完成重定向
重定向(Redirect):一种资源跳转方式
实现方式:
resp.setStatus(302);
resp.setHeader("location",“资源B的路径");
resp.sendRedirect("资源B的路径");
重定向的特点
浏览器地址栏路径发生变化可以重定向到任意位置的资源(服务器内部、外部均可)两次请求,不能在多个资源使用request共享数据
路径问题
是否要加虚拟目录
明确路径谁使用?浏览器使用:需要加虚拟目录(项目访问路径)服务端使用:不需要加虚拟目录
//简化方式完成重定向
//动态获取虚拟目录
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/resp2");
3.Response响应字符数据
使用1.通过Response对象获取字符输出流
PrintWriter writer = resp.getWriter()
2.写数据
writer.write("aaa");
正常写入数据就调用write方法即可,如想要写入html文本语言,则要设置ContentType
response.setContentType("text/html;charset=utf-8");
//1.获取字符输出流
PrintWriter writer response.getWriter();
//content-type
//response.setHeader("content-type","text/html");
writer.write(s:"你好");
writer.write(s:"<h1>aaa</h1>");
//细节:流不需要关闭
注意该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1
resp.setContentType("text/html;charset=utf-8");
4.Response响应字节数据
使用1.通过Responsel对象获取字符输出流
ServletOutputStream outputStream = resp.getOutputStream();
2.写数据
outputStream,write(字节数据):
IOUtils工具类使用1.导入坐标
<dependency>
<groupld>commons-io</groupld>
<artifactld>commons-io</artifactld>
<version>2.6</version>
</dependency>
2.使用
IOUtils.copy(输入流,输出流);
5.SqlSession工具类抽取
创建SqlSessionFactory代码优化
//2.1获取SqlSessionFactory对象
String resource "mybatis-config.xml";
Inputstream inputstream = Resources.getResourceAsstream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
问题1.代码重复:工具类2.SqlSessionFactory工厂只创建一次,不要重复创建:静态代码块