🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 获得请求行 获得客户端的请求方式:`String getMethod()` 获得请求的资源: ~~~ String getProtocol() --获取协议版本 String getRequestURI() --获取请求的uri StringBuffer getRequestURL() String getContextPath() ---web应用的名称 String getQueryString() ---- get提交url地址后的参数字符串 username=zhangsan&password=123 getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。 getRemoteAddr方法 返回发出请求的客户机的IP地址。 getRemoteHost方法 返回发出请求的客户机的完整主机名。 getRemotePort方法 返回客户机所使用的网络端口号。 getLocalAddr方法 返回WEB服务器的IP地址。 getLocalName方法 返回WEB服务器的主机名 getLocale方法 返回浏览器端国家语言信息 ~~~ URI——用于标识(任意)一个资源,如`/news/1.html`、`c:\abc\a.txt` URL——用于标识互联网上的一个资源,如`http://www.sina.com/news/1.html ` 所以URI包含URL 注意:request可获得客户机(客户端)的一些信息 ~~~ request.getRemoteAddr() --- 获得访问的客户端IP地址 ~~~ # 获得请求头 ~~~ long getDateHeader(String name) String getHeader(String name) Enumeration getHeaderNames() Enumeration getHeaders(String name) int getIntHeader(String name) ~~~ referer头的作用:执行该此访问的的来源,做防盗链 # 获得请求体 请求体中的内容是通过post提交的请求参数,格式是: ~~~ username=zhangsan&password=123&hobby=football&hobby=basketball key ---------------------- value username [zhangsan] password [123] hobby [football,basketball] ~~~ 以上面参数为例,通过一下方法获得请求参数: ~~~ String getParameter(String name) String[] getParameterValues(String name) Enumeration getParameterNames() Map<String,String[]> getParameterMap() ~~~ 注意:get请求方式的请求参数 上述的方法一样可以获得 解决post提交方式的乱码:`request.setCharacterEncoding("UTF-8");` 解决get提交的方式的乱码(每一个参数都要这样): ~~~ parameter = new String(parameter.getBytes("iso8859-1"),"utf-8"); ~~~ post请求要注意 servlet规范:同时满足下列条件,则请求体中的数据将被填充到Parameter集合中 1. 是一个http/https请求 2. 请求方法是post 3. 请求类型(content-Type)是application/x-www-form-urlencoded 4. Servlet调用了getParameter系列方法 # 示例 ## 根据参数名获取值 get 方法获取 ~~~ String name = request.getParameter("name"); String age = request.getParameter("age"); ~~~ ## 取其他信息 ~~~ //主机地址 String serverName = request.getServerName(); //端口 int port = request.getServerPort(); // http://localhost:8080/javaWeb/MyServlet 中的 /javaWeb String path = request.getContextPath(); //查询字符串 name=jdxia&age=17 String queryString = request.getQueryString(); ~~~ ## 转发 获得请求转发器----path是转发的地址 ~~~ RequestDispatcher getRequestDispatcher(String path) ~~~ 通过转发器对象转发 ~~~ requestDispathcer.forward(ServletRequest request, ServletResponse response) RequestDispatcher requestDispathcer = request.getRequestDispatcher("/MyRequest"); requestDispathcer.forward(request, response); ~~~ **浏览器只发起一次请求** ~~~ //转发 获取转发器需要参数:请求转发给哪个资源文件处理 //这边路径是相对于编译后的 RequestDispatcher dispatcher = request.getRequestDispatcher("1.html"); //发起转发 dispatcher.forward(request, response); ~~~ ### 请求转发的细节 forward方法用于将请求转发到RequestDispatcher对象封装的资源上。 如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常。 例,以下代码会抛出异常: `java.lang.IllegalStateException: Cannot forward after response has been committed` ~~~ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "aaaaaa"; PrintWriter writer = response.getWriter(); writer.write(data); writer.close(); /* * 以下跳转会导致: java.lang.IllegalStateException: Cannot forward after * response has been committed */ request.getRequestDispatcher("/message.jsp").forward(request, response); } ~~~ 虽然你不会写出以上愚蠢的代码,但是你会写出如下糟糕的代码,这是在所难免的。 ~~~ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "aaaaaa"; if(true) { request.getRequestDispatcher("/index.jsp").forward(request, response); } /* * 以下跳转会导致: java.lang.IllegalStateException: Cannot forward after * response has been committed */ request.getRequestDispatcher("/message.jsp").forward(request, response); } ~~~ 所以要记住:**每次跳转之后一定要return** ~~~ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "aaaaaa"; if(true) { request.getRequestDispatcher("/index.jsp").forward(request, response); return; // 每次跳转之后一定要return } request.getRequestDispatcher("/message.jsp").forward(request, response); } ~~~ 如果在调用forward方法之前向Servlet引擎的缓冲区中写入了内容,只要写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空,但是,已写入到HttpServletResponse对象中的响应头字段信息保持有效 ~~~ // forward的细节,forward时,会清空response中的数据 public class RequestDemo7 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "aaaaaa"; response.getWriter().write(data); // 跳转之前会把原来写入response的数据清空 request.getRequestDispatcher("/index.jsp").forward(request, response); } ~~~ # 域对象 request对象也是一个存储数据的区域对象,所以也具有如下方法: ~~~ setAttribute(String name, Object o) getAttribute(String name) removeAttribute(String name) ~~~ 注意: **request域的作用范围:一次请求中** # ServletContext域与Request域生命周期 ServletContext: 创建:服务器启动 销毁:服务器关闭 域的作用范围:整个web应用 request: 创建:访问时创建request 销毁:响应结束request销毁 域的作用范围:一次请求中