前言
一、Request&Response干什么?
二、Request
(一)Request继承体系
(二)获取的请求数据
1.请求行
2.请求头
3.请求体
(三)通用的方式请求参数
1.因为获取的参数为编辑
2.切割
3.所以提供了三种通用方法
4.实际代码
5.与鸿蒙arkts交互的特殊情况
(四)解决request乱码问题
1.dopost解决乱码方法:
2.doget解决乱码的方法:
(五)reques请求转发
1.概念
2.实现方式
3.共享数据的方法
4.请求转发的特点
三、Response
(一)Response设置响应数据功能接介绍
1.响应行:编辑
2:响应头编辑
3.响应体:编辑
(二)Response重定向
1.概念
2.重定向代码
3.重定向特点
3.资源路径问题
(三)Response响应字符数据
(四)Response响应字节数据
这两个知识点,就是http的具体接收,回应的代码了。学会这个前后端就可以进行简单的交互了。相当于python的django框架。不管是django与这个知识点都可以与鸿蒙前端进行简单的前后端交互了。
Request:服务器获取的请求数据
Response:设置向客户端响应数据
主要就是使用HttpServletRequest,在实现HttpServlet接口时候,在doPost/Get里的参数就是HttpServletRequest。
1.Tomcat需要解析传输数据,封装为request对象,并且创建request对象,传到serivce方法中,所以实现类就tomcat直接实现。
2.使用request对象,接口的实现类,直接可以使用HttpServletRequest接口的方法。
String getMethond():获取请求方式
String getContextPath():获取虚拟目录(项目的访问路径)
StringBuffer getRequestURL():获取URL(统一资源定位符)------包括ip和端口
String getRequestURL():获取URI(统一资源定位符)------不包括ip和端口
String getQueryString():获取请求参数(GET方式)
String getHeader(String name):根据请求头的每次,获取值
只有post特有的,post请求的数据
ServletInputStream getInputStream():获取字节输入流
BufferedReader getReader();获取字符输入流
GET方式:String getQueryString()
POST:BufferedReader getReader()
所以doget和dopost方法要写两遍非常的麻烦,因此是否存在一种通用的代码来请求参数呢
因此request提供方法,将其切割,装入map集合内,实现键值对
Map
String[] getParameterValues(String name):根据名称获取参数值
String getParameter(String name):根据名称获取参数值(单个值)
@WebServlet("/httptesy")
public class httptest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Map map=req.getParameterMap();
for (String key : map.keySet()) {
System.out.print(key+":");
String[] values = map.get(key);
for (String value : values) {
System.out.print(value+" ");
}
System.out.println();
}
String uesrname = req.getParameter("username");
String password = req.getParameter("password");
resp.getWriter().write("登录成功");
System.out.println(uesrname+" "+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
因为doget和dopost代码相同,因此两者dopost中把doget写入dopost内,减少代码使用。
在与鸿蒙前端交互中,发现让前端为post模式发送数据,java使用通用方法收到的数据怎么都为空,而get方法都可以正常使用。发现,鸿蒙以post方式传来的数据和get方法,以及html的post方法传来的数据不同。只能通过post的特有的方法BufferedReader来查看。查看结果如下
而其他方式如html方式
而用通用方法是按照=和&符号分割的,因此上方鸿蒙传递来的参数无法分割也就无法实现直接通用参数获取。
tomcat8之后没有乱码问题,但是post用流打印还是中文十六进制,见下面解码代码区可以解决
req.setCharacterEncoding("UTF-8");
因为网页不支持中文,将中文转化为两个16进制数的形式。tomcat解码默认为iso-8859-1编码解码不同。
先给出方法编码和解码
//URL编码
String encode= URLEncoder.encode(username,"utf-8");
System.out.println(encode);
//URL解码
String decode = URLDecoder.decode(username, "utf-8");
System.out.println(decode);
获取的username是被iso-8859-1解码了,所有先把username转为字节数组,数值内的值为开始十六进制的二进制形式,再把字节数组转为字符串,就是原来的汉字了。
byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
String s1 = new String(bytes, StandardCharsets.UTF_8);
System.out.println(s1);
也可以解决post的乱码
请求转发(forward):一种在服务器内部资源跳转方式。
跳转过程称为转发(forward)
req.getRequestDispatcher("跳转的那个个资源的路径").forward(req,resp)
void setAttribute(String name,Object o):存储数据到request域中
Object getAttribute(String name):根据key,获取值
void removeAttribute(String name):根据key,删除键值对
浏览器的路径不发生变化
转发只能转发到服务器内部的资源
一次请求,可以转发的资源间使用request共享数据
就是设置响应数据的
体系结构:
协议,版本号,状态码,状态码的描述
void setStatus(int sc)响应状态码
void setHeader(String name,String value):设置响应头键值对
PrintWriter getWriter():获取字符输出流
ServletOutputStream getOutputStream():获取字节输出流
重定向:一种资源跳转方式
资源A处理不了回到别的资源请求.。
302状态码
方法1
resp.setStatus(302)
resp.setHeader("location","/项目路径/资源B路径")
//location固定的
方法2
resp.senRedirect("/项目路径/资源B路径");
浏览器地址栏路径发送变化
可以重定向任何位置(外部,内部服务器都可以)
两次请求,不能在多个资源使用
重定向时候跳转("/项目路径/资源B路径");也就是("/虚拟目录/资源B路径");
而请求转发req.getRequestDispatcher("/ 资源B路径").forward(req,resp)
什么时候是加虚拟目录呢?
明确路径给谁用
浏览器使用:需要加虚拟目录
服务端使用:不需要加
代码实例:
//响应字符数据
PrintWriter writer1=resp.getWriter();
writer1.write("aaa");
//响应html数据
resp.setHeader("content-type","text/html");
writer1.write("aaa
");
//响应中文数据(tomcat8以上就可以直接响应了)
resp.setContentType("text/html;charset=utf-8");
writer1.write("你好");
细节:流不需要关闭
代码:
//1.读取文件
FileInputStream fis=new FileInputStream("D:\\study\\biancheng\\javaweb\\javaweb_test\\add1.png");
//2.获取response此节输出流
ServletOutputStream os = resp.getOutputStream();
//完成流copuy
byte[] buff=new byte[1024];
int len;
while ((len=fis.read(buff))!=-1){
os.write(buff,0,len);
}
fis.close();
但是因为io拷贝很麻烦,因此工具类,靠maven导入jar包,有更方便的方法,依赖坐标:
commons-io commons-io 2.13.0
代码:
//1.读取文件
FileInputStream fis=new FileInputStream("D:\\study\\biancheng\\javaweb\\javaweb_test\\add1.png");
//2.获取response此节输出流
ServletOutputStream os = resp.getOutputStream();
//完成流copuy
// byte[] buff=new byte[1024];
// int len;
// while ((len=fis.read(buff))!=-1){
// os.write(buff,0,len);
// }
IOUtils.copy(fis,os);
fis.close();