目录
一、概念
1.当我们用浏览器访问服务器的时候,服务器(tomcat)会用servlet方法去处理我们的请求并做出响应。
二、请求(Request)
1.例子简介
用户使用get(地址栏可以看到具体信息)或者post(地址栏可以看到具体信息)请求访问时候里面都会携带很多数据,例如账户名密码这些,那么Request就会获取这些数据。
2.Request继承体系
爷爷----SevletRequest:Java对象提供的请求对象根接口
父亲----HttpServleRequest:Java提供的对Http协议封装的请求对象接口
儿子----RequestFacade:Tomcat定义的实现类
ps:使用Request时候使用HttpServleRequest就好了
3.Request获取请求数据
请求数据分为3部分
(1)请求行
获取请求方式(GET):getMethod
获取虚拟目录(项目访问路径):getContextPath
获取URL(统一资源定位符):getRequestURL
获取URI(统一资源标识符):getRequestURI
获取请求参数(GET方式):getQueryString
(2)请求头
获取请求头:getHeader
(3)请求体
字节或者字符输入流读取,具体看要要求参数
具体代码
调用方式就是用注解调用ddd
package com.project.JavaScript;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedReader;import java.io.IOException;@WebServlet("/ddd")public class aa extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //一、获取请求行 //1.getMethod:获取请求方式:GET String method = req.getMethod(); System.out.println(method); //2.getContextPath:获取虚拟目录 String contextPath = req.getContextPath(); System.out.println(contextPath); //3.getRequestURL:获取URL(统一资源定位符) StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURL); //4.getRequestURI:获取统一资源标识符 String requestURI = req.getRequestURI(); System.out.println(requestURI); //5.getQueryStrin:获取请求参数(GET方式) String queryString = req.getQueryString(); System.out.println(queryString); //二获取请求头 // 6.获取请求头:user-agen--浏览器的版本信息 String agent = req.getHeader("user-agent"); System.out.println(agent); //三、获取请求体 //1.获取字节输入流 BufferedReader reader = req.getReader(); //2.读取数据 String line = reader.readLine(); System.out.println(line); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //如果有post请求就让它去doGet里面找吧 this.doGet(req,resp); }}
如下是为了第三的请求体有东西调用而写的一个html表单
调用方式:运行的网页地址加上这个html名字(req.html)
Title
运行结果
POST
/maven_java_war
http://localhost:8080/maven_java_war/ddd
/maven_java_war/ddd
null
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.46
username=666&password=666666
4.优化请求体参数的获取
上面在获取请求体的时候还不是很好,现在要优化,把请求体中的数据放到Map集合中,再通过map集合的方式获取出来
获取全部Map集合的方法:getParameterMap
获取数组Map集合的方法:getParameterValues
获取单个Map集合的方法:getParameter
被获取的HTML代码
Title
获取代码
package com.project.JavaScript;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Map;@WebServlet("/ddd")public class aa extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //一、获取全部 //1.获取所有参数的Map集合 Map map = req.getParameterMap(); //2.遍历快捷键:iter+回车 for (String key : map.keySet()) { System.out.println("key为:"+key); //3.获取值 String[] values = map.get(key); //4.遍历快捷键:iter+回车 for (String value : values) { System.out.println("map集合的全部为:"+value); } } System.out.println("===========分界线==============="); //二、根据key,也就是键获取数组 String[] hobbies = req.getParameterValues("hobby"); for (String hobby : hobbies) { System.out.println("这是第二种方式的运行结果"+hobby); } System.out.println("===========分界线==============="); //三、根据key,获取单个值 String username = req.getParameter("username"); String password = req.getParameter("password"); System.out.println("用户名为:"+username); System.out.println("密码为:"+password); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //如果有post请求就让它去doGet里面找吧 this.doGet(req,resp); }}
运行结果
key为:username
map集合的全部为:zhangsan
key为:password
map集合的全部为:1433223dadqw
key为:hobby
map集合的全部为:1
===========分界线===============
这是第二种方式的运行结果1
===========分界线===============
用户名为:zhangsan
密码为:1433223dadqw
5.解决请求参数乱码问题
6.请求转发
请求转发(forward):一种在服务器内部的资源跳转方式。当访问了资源A,资源A处理了一部分,然后在转发给资源B处理。
请求转发的特点
(1)浏览器地址栏路径不发生变化
(2)只能转发到当前服务器的内部资源
(3)一次请求,可以在转发的资源使用request共享数据
转发的代码
//tt是下一步要转到的目标类的注解
request.getRequestDispatcher("tt").forward(request,response);
其他方法
void setAttribute(String name,Object o);//储存数据到request域中
Object getAttribute(String name);//根据key,获取值
void removeAttribute(String name);//根据key,删除键值对
三、响应(Response)
1.Response继承体系
爷爷----SevletResponse:Java对象提供的请求对象根接口
父亲----HttpServleResponse:Java提供的对Http协议封装的请求对象接口
儿子----ResponseFacade:Tomcat定义的实现类
ps:使用Request时候使用ttpServleResponse就好了
2.设置响应数据功能介绍
(1)响应行
例子:HTTP/1.1 200 OK
ps:HTTP/1.1是服务器版本,200是响应状态码,OK就是没问题
设置响应状态码:void setStatus(int sc);
(2)响应头
例子:Content-Type:text/html
设置响应头键值对:void setHeads(String name,String value);
(3)响应体
例子:
head>获取字符输出流:PrintWriter getWriter();
获取字节输出流:ServletOutputStream();
3.重定向
一种资源跳转方式(例如访问资源A,A说我处理不了,我告诉你资源B的地址,你去找它处理吧)。那怎么处理不了怎么通知对方呢,就是用状态码302代表说我处理不了,对方地址是:响应头location:xxxxxx
(1)实现方式:
resp.setStatus(302);
resp.setHeader("location","资源B的路径");
这是简写方式
//重定向 //设置响应头:baidu是跳转目标类的注解 response.sendRedirect("baidu");
(2)重定向特点
浏览器地址栏路径发生变化
可以重定向到任意位置的资源(服务器内外部都可以)
两次请求,不能在多个资源使用request共享数据
4.资源路径问题
浏览器使用:需要加虚拟目录(项目访问路径)
服务端使用:不需要加虚拟目录
(1)怎么判断谁使用?
有请求(request)或者响应(response)这些都是服务端使用。但是转发是个例外。其余的都是浏览器使用(标签什么的)
(2)怎么使用虚拟目录呢?
一般在pom.xml文件配置的path里面可以设置,但是一般不建议,这样耦合度太高
所以要把里面我的默认访问/a删掉。 然后在要访问的类里面设置一个动态虚拟访问路径语句
//重定向 //动态获取虚拟目录 String contextPath = request.getContextPath(); //设置响应头:baidu是跳转目标类的注解。然后动态虚拟目录+注解 response.sendRedirect(contextPath+"/baidu");
5.Response响应字符数据
//1.设置字符集编码解析 response.setContentType("text/html;charset=utf-8"); //2.获取字符输入流 PrintWriter writer = response.getWriter(); //写入中文 writer.write("你好"); //写入标签 writer.write("aa
");
6.Response响应字节数据
(1) 相对复杂写法
//1.字节输入流读取文件 FileInputStream fis = new FileInputStream("D:\\图片\\个人\\杂物\\小图片.png"); //2.获取response字节输出流 ServletOutputStream os = response.getOutputStream(); //3.完成流的复制 byte[] bytes = new byte[1024]; int len = 0; while ((len = fis.read(bytes))!=-1){ os.write(bytes,0,len); }
(2)简单的写法
//1.字节输入流读取文件 FileInputStream fis = new FileInputStream("D:\\小图片.png"); //2.获取response字节输出流 ServletOutputStream os = response.getOutputStream(); //3.使用便捷的方式完成流的copy IOUtils.copy(fis,os); //关闭流 fis.close();
ps:使用这个简单的写法要pom里面导入对应的maven。要不然爆红用不了的
commons-io commons-io 2.6
来源地址:https://blog.csdn.net/m0_52861000/article/details/128316101