package servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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;
import java.util.Enumeration;
@WebServlet("/reqdemo")
public class TestReqServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get"+req);
System.out.println(req.getMethod());
System.out.println(req.getQueryString()); //获取get方式的请求参数
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("post"+req); //postorg.apache.catalina.connector.RequestFacade@43c82cad
System.out.println(req.getMethod()); //POST
System.out.println(req.getContextPath()); ///812_req_war_exploded
System.out.println(req.getServletPath()); ///reqdemo
System.out.println(req.getRequestURI()); ///812_req_war_exploded/reqdemo
System.out.println(req.getRequestURL()); //http://localhost:8080/812_req_war_exploded/reqdemo
System.out.println(req.getProtocol()); //HTTP/1.1
System.out.println(req.getRemoteAddr()); //0:0:0:0:0:0:0:1
System.out.println(req.getQueryString()); //null
//以上都是关于请求行的信息获取操作
//test可知,默认的方式是get,如果表单的提交方式有设置为post,那么doGet方法体无视
//如果从浏览器直接访问本Servlet,就是默认get
//这样就很不安全,比如如果这个Servlet将参数获取并写入数据库,不停的攻击这个Servlet,就打爆了数据库.
//所以要想一个方法,只有通过了一些判断才能访问这个Servlet
//关于请求行有两个方法需要注意
//getRequestURI(); 也就是统一资源标识符
//getRequestURL(); 也就是统一资源定位符
//范围大小: 资源标识符 > 资源定位符
System.out.println("-----------------------------------------------------------------------------------------------------");
//Enmeration<String> getHeadernames();
Enumeration<String> headNames = req.getHeaderNames(); //获取该次请求的所有请求头key
while(headNames.hasMoreElements()){
String elementkey = headNames.nextElement();
String elementvalue = req.getHeader("elementkey");//通过请求头的key,获取value
System.out.println(elementkey+":"+elementvalue);
}
/*
host:null
connection:null
content-length:null
cache-control:null
sec-ch-ua:null
sec-ch-ua-mobile:null
upgrade-insecure-requests:null
origin:null
content-type:null
user-agent:null
accept:null
sec-fetch-site:null
sec-fetch-mode:null
sec-fetch-user:null
sec-fetch-dest:null
referer:null
accept-encoding:null
accept-language:null
cookie:null
*/
System.out.println(req.getHeader("user-agent")); //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
System.out.println(req.getHeader("referer")); //http://localhost:8080/812_req_war_exploded/
//以上就是请求头信息的获取
//Enumeration<String>这个容器可以当做迭代器来使用
//存放请求头的所有key的这么一个容器
//他的对象有两个方法
//hasMoreElements(); //判断当前指针之后还有没有存放对象
//nextElement(); //将指针跳到下一个对象
//后面对头的key熟悉之后
//直接使用String getHeader(String key); 通过请求头的key,获取value
//这里补充复习一个String的方法
//String类型有一个方法:contains(),该方法是判断字符串中是否有子字符串。如果有则返回true,如果没有则返回false。这个方法是对getHeader获取的value的进一步使用必备方法
System.out.println("-----------------------------------------------------------------------------------------------------");
BufferedReader postInput = req.getReader();
String line = null;
while ((line = postInput.readLine())!= null){
System.out.println(line);
}
//以上就是请求体的信息的获取
//请求体是只有post方式才有的信息
//Servlet中有两种容器可以存放请求体的信息
//一种是字符流BufferedReader : 只能操作字符数据
//他的对象有readLine();方法可以获取指针当前行的String数据,并且执行完该方法一次就会将指针下移一次.
//一种是字节流ServletInputStream : 能操作所有类型的数据
//针对的是文件上传的技术
System.out.println("-----------------------------------------------------------------------------------------------------");
//String getParameter(String name); 根据参数名称获取参数值
//String[] getParameterValues(String name); 根据参数名称获取参数的值的数组
//Enumerate<String> getParameterNames(); 获取所有参数的name
//Map<String, String[]> getParameterMap(); 获取所有参数的map集合
//以上就是req的通用的获取参数的方式
//相比于get方式的getQueryString();获取字符串
//或者post方式的字符流方式获取请求体一行一行的字符串
//通用方法直接利用元素的name属性获取对应的value或者values
//这样一来get和post唯一的区别也就不存在了可以直接用this.doPost(req. resp);写在doGet里面,这样一来就不用写两份代码,得以简化开发.
//这里有需要补充复习的两个方法,是关于Map的操作的
//得到Map<String, String[]>的对象之后,可以用keySet();方法,获取Map中key的并封装成数组对象,利用foreach循环,单独的将各个key拿出来操作,Map<String, String[]>的对象还
//有一个get(String key)方法,可以获取Map的各个value对象,再进行一层循环即可.
//接下来就是中文乱码的问题
//信息在不同平台之间跳转的时候,总难免考虑一个编码格式的问题
//这里接受req的信息之前一般要先req的编码问题解决掉, 可是,每一个Servlet都写这样的不烦吗,还有Servlet的一个安全访问问题,其实是同一个问题,如果在req到达Servlet之前,能够进行一些逻辑处理不就好了
//setCharacterEncoding("utf-8");
System.out.println("-----------------------------------------------------------------------------------------------------");
/*
* req一般是由浏览器出
* 从服务器入
* 也就是说
* req的来源一般都是浏览器
* 但是req就没有别的来源了吗
* 能不能来自服务器呢?
* 或者说req的终点就只是一个Servlet吗?
*
* Servlet中有一个工具对象叫做req转发器
* RequestDispatcher
* 可以由req的getRequestDispatcher(String path);方法获取
* RequestDispatcher的对象创建出来之后,就可以使用他的forward(req, resp);方法将本地Servlet接受到的req给转发到别的地方处理
*
* 注意的是:
* Servlet中的这种req转发器
* 只能认识服务器的内部资源.也即是说不在服务器内部的资源是无法转发的
* 还有就是浏览器本身只认识第一个接受我req的资源地址,后面间接接受我这次req的资源,浏览器表示与我何干.
*
* 这样一个问题就接踵而至
* 就是浏览器我这一次req同时被你们这么多Servlet同时处理过
* 那老子怎么接受你们的resp呢
* 接受谁的好呢
* 还有
* 既然一次req的处理让多个Servlet分摊了
* 那么,AServlet用不用告诉BServlet做了什么工作了呢
* 也就是说,AServlet除了给BServlet转发了req之外,用不用还随之发送一些个信息呢
*
* */
System.out.println("-----------------------------------------------------------------------------------------------------");
/*要解决以上的两个问题
* 首先就要理解什么是域对象 : 也就是一个保存信息的信息对象,同时可以被好多个进程处理,能处理这个信息对象的进程就组成一个域,在这个域总可以共享req的数据
* 补充: 通过req还能直接获取另一个域对象(ServletContext), 这个域对象的范围就不仅仅是req一次的web资源,而是所有的资源.
* req就是其中一种域对象
* req除了本身从浏览器那里来的http请求信息,还能在服务器端开辟一块只有域内进程才能获取的数据存放空间
* void setAtribute(String name, Object object); 存储数据
* Object getAttribute(String name); 通过键获取值
* void removeAttribute(String name); 移除一个键值对
* 那么问题就来了
* 除了第一个Servlet,转发的Servlet还能接受http请求信息吗,还是只能要服务器端里数据空间的信息 (而这就是解开以上第一个问题的关键)
* */
System.out.println("-----------------------------------------------------------------------------------------------------");
//req学到这里也算差不多了
//但是还有两个问题没有答案
//这里建议先去看一下最高层的域对象
//ServletContext
}
}
请求消息req
最新推荐文章于 2024-09-14 09:06:38 发布