request对象
2016-07-16 11:12
531 查看
HttpServletRequest介绍
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。Request常用方法
获得客户机信息
getRequestURL方法返回客户端发出请求时的完整URL。getRequestURI方法返回请求行中的资源名部分。
URI——用于标识(任意)一个资源,如
/news/1.html、
c:\abc\a.txt。
URL——用于标识互联网上的一个资源,如
http://www.sina.com/news/1.html。
所以URI包含URL。
getQueryString方法返回请求行中的参数部分。
getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
getRemoteAddr方法返回发出请求的客户机的IP地址。
getRemoteHost方法返回发出请求的客户机的完整主机名。
getRemotePort方法返回客户机所使用的网络端口号。
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名。
范例:通过request对象获取客户端请求信息。
// request的常用方法 public class RequestDemo1 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // getRequestURI()得到你访问的资源 System.out.println(request.getRequestURI()); // 打印/day06/RequestDemo1 System.out.println(request.getRequestURL()); // 打印http://localhost:8080/day06/RequestDemo1 // http://localhost:8080/day06/RequestDemo1?name=aaa System.out.println(request.getQueryString()); System.out.println("----------------------------------"); System.out.println(request.getRemoteAddr()); // 打印127.0.0.1 System.out.println(request.getRemoteHost()); System.out.println(request.getRemotePort()); System.out.println(request.getMethod()); // 得到请求URL地址时使用的方法 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
运行:
获得客户机请求头
getHeader(string name)方法:String。getHeaders(String name)方法:Enumeration。
getHeaderNames()方法。
范例:通过request对象获取客户端请求头信息。
// 获取请求头 public class RequestDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("------------------获取请求头方式1------------------"); String headValue = request.getHeader("Accept-Encoding"); // 根据请求头的名字获取对应的请求头的值 System.out.println(headValue); System.out.println("------------------获取请求头方式2------------------"); Enumeration<String> e = request.getHeaders("Accept-Encoding"); // 根据请求头的名字获取所有对应请求头的值 while(e.hasMoreElements()) { String value = e.nextElement(); System.out.println(value); } System.out.println("------------------获取请求头方式3------------------"); e = request.getHeaderNames(); // 获取所有的请求头 while(e.hasMoreElements()) { String name = e.nextElement(); String value = request.getHeader(name); System.out.println(name+"="+value); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
获得客户机请求参数(客户端提交的数据)
getParameter(String)方法(常用)。getParameterValues(String name)方法(常用)。
getParameterNames()方法(不常用)。
getParameterMap()方法(编写框架时常用)。
比如现在有如下的form表单——test.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>带数据给RequestDemo2</title> </head> <body> <!-- url后面如果跟了中文数据,要编码后再提交 --> <a href="/day06/RequestDemo2?username=zzz">点点</a> <form action="/day06/RequestDemo2" method="post"> 用户名1:<input type="text" name="username"><br/> 用户名2:<input type="text" name="username"><br/> 密码:<input type="text" name="password"><br/> <input type="submit" value="提交"> </form> </body> </html>
必须注意:url后面如果跟了中文数据,要编码后再提交。如:
<a href="/day06/RequestDemo2?username=中国">点点</a>
在form表单中填写数据,然后提交到RequestDemo2这个Servlet进行处理,填写的表单数据如下:
在服务器端使用getParameter方法和getParameterValues方法接收表单参数,代码如下:
// 获取请求数据(获取请求数据时一般来说都要先检查再使用) public class RequestDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("-----------------获取数据方式1----------------------"); String value = request.getParameter("username"); // 获取请求数据时一般来说都要先检查再使用 if(value!=null && !value.trim().equals("")) { System.out.println(value); } System.out.println("-----------------获取数据方式2----------------------"); String[] values = request.getParameterValues("username"); /* for(String v : values) { System.out.println(v); } */ // 获取数组数据的技巧,可以避免values数组为null时引发的空指针异常错误! for(int i=0;values!=null && i<values.length;i++) { System.out.println(values[i]); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在服务器端使用getParameterNames方法接收表单参数,代码如下:
// 获取请求数据(获取请求数据时一般来说都要先检查再使用) public class RequestDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("-----------------获取数据方式3----------------------"); Enumeration<String> e = request.getParameterNames(); // 获取所有的参数名 while(e.hasMoreElements()) { String name = e.nextElement(); // username password value = request.getParameter(name); System.out.println(name+"="+value); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在服务器端使用getParameterMap方法接收表单参数。
此时要通过一个JavaBean来封装从表单提交过来的数据,设计一个表示用户的JavaBean——User.java。
public class User { private String username[]; private String password; public String[] getUsername() { return username; } public void setUsername(String[] username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
在服务器端使用getParameterMap方法接收表单参数,然后用map集合的数据填充bean。
// 获取请求数据(获取请求数据时一般来说都要先检查再使用) public class RequestDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("-----------------获取数据方式4----------------------"); Map<String, String[]> map = request.getParameterMap(); User user = new User(); try { /* * 在实际开发中,非常实用 * 用map集合的数据填充bean */ BeanUtils.populate(user, map); /* * 在实际开发中,也是非常实用 * 从formbean将属性拷贝到user中去,bean的拷贝 */ // BeanUtils.copyProperties(user, formbean); } catch (Exception e1) { e1.printStackTrace(); } System.out.println(user); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
此时涉及到Beanutils工具包的使用,可参考我的笔记内省。
在服务器端使用getInputStream方法接收表单参数,通常用在获取文件上传上。
// 获取请求数据(获取请求数据时一般来说都要先检查再使用) public class RequestDemo2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("-----------------获取数据方式5----------------------"); // 通常用在获取文件上传上 InputStream in = request.getInputStream(); int len = 0; byte[] buffer = new byte[1024]; while((len=in.read(buffer)) != -1) { System.out.println(new String(buffer, 0, len)); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
以上代码运行之后,没有显示出数据,我不知道为什么,谁能告诉下我!!!
各种表单输入项数据的获取
比如现在有如下的form表单——form.html:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>各种表单输入项数据的获取</title> </head> <body> <form action="/day06/RequestDemo3" method="post"> 用户名:<input type="text" name="username"><br/> 密码:<input type="password" name="password"><br/> 性别: <input type="radio" name="gender" value="male">男 <input type="radio" name="gender" value="female">女<br/> 所在地: <select name="city"> <option value="beijing">北京</option> <!-- value代表提交给服务器的值,每一个数据必须要有一个名称,服务器根据名称获取对应的值--> <option value="shanghai">上海</option> <option value="wuhan">武汉</option> </select><br/> 爱好: <input type="checkbox" name="likes" value="sing">唱歌 <input type="checkbox" name="likes" value="dance">跳舞 <input type="checkbox" name="likes" value="basketball">篮球 <input type="checkbox" name="likes" value="football">足球<br/> 备注: <textarea rows="6" cols="60" name="description"></textarea><br/> 大头照: <input type="file" name="image"><br/> <input type="hidden" name="id" value="123456"> <!-- 隐藏输入项 --> <input type="submit" value="提交"> </form> </body> </html>
value代表提交给服务器的值,每一个数据必须要有一个名称(name),服务器根据名称(name)获取对应的值(value)。
在form表单中填写数据,然后提交到RequestDemo3这个Servlet进行处理,填写的表单数据如下:
在服务器端接收表单参数,代码如下:
public class RequestDemo3 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(request.getParameter("username")); System.out.println(request.getParameter("password")); System.out.println(request.getParameter("gender")); System.out.println(request.getParameter("city")); String[] likes = request.getParameterValues("likes"); for(int i=0;likes!=null && i<likes.length;i++) { System.out.println(likes[i]); } System.out.println(request.getParameter("description")); System.out.println(request.getParameter("id")); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
防盗链
Servlet——RequestDemo9代码:// 防盗链 public class RequestDemo9 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 得到来访者从哪个资源来访问服务器 String referer = request.getHeader("Referer"); /* * 若来访者直接在浏览器地址栏输入http://localhost:8080/day06/RequestDemo9, * 即来访者没从任何页面点过来,则referer == null */ if(referer == null || !referer.startsWith("http://localhost")) { // 必须得用重定向,要明确告诉来访者跳到首页上面去了 response.sendRedirect("/day06/index.jsp"); return; // 重定向完了之后后面的代码不需要执行,所以要return } String data = "凤姐日记"; response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(data); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="/day06/ResponseDemo6">查看图书</a> <br/>看广告<br/> <a href="/day06/RequestDemo9">看凤姐</a> </body> </html>
运行结果:
在浏览器地址栏输入
http://localhost:8080/day06/RequestDemo9,并回车,此时跳转到首页。
点击
看凤姐。
request接收表单提交中文参数乱码问题
以POST方式提交表单中文参数的乱码问题
例如有如下的form表单页面:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>request接收中文参数乱码问题</title> </head> <body> <form action="/day06/RequestDemo4" method="post"> 用户名:<input type="text" name="username"><br/> <input type="submit" value="提交"> </form> </body> </html>
此时在服务器端接收中文参数时就会出现中文乱码,如下所示:
public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); System.out.println(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
post方式提交中文数据乱码产生的原因和解决办法
用抽象一点的图来表示:用具体一点的图来表示:
可以看到,之所以会产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收。
由于客户端是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器也需要设置以UTF-8字符编码进行接收,要想完成此操作,服务器可以直接使用从ServletRequest接口继承而来的”setCharacterEncoding(charset)”方法进行统一的编码设置。修改后的代码如下:
// 解决post提交的乱码 public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); // 只对客户机的post方式提交有效 String username = request.getParameter("username"); System.out.println(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
使用
request.setCharacterEncoding("UTF-8");设置服务器以UTF-8的编码接收数据后,此时就不会产生中文乱码问题了。
以GET方式提交表单中文参数的乱码问题
例如有如下的form表单页面:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>request接收中文参数乱码问题</title> </head> <body> <form action="/day06/RequestDemo4" method="get"> 用户名:<input type="text" name="username"><br/> <input type="submit" value="提交"> </form> </body> </html>
此时在服务器端接收中文参数时就会出现中文乱码,如下所示:
public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); System.out.println(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
get方式提交中文数据乱码产生的原因和解决办法
post/get方式提交中文数据乱码产生的原因都是一样的。
对于以get方式传输的数据,request即使设置了以指定的编码接收数据也是无效的(因为它只对客户机的post方式提交有效),客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致因此才会产生中文乱码的。解决办法:在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。
// 解决get提交的乱码(手工处理) public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); username = new String(username.getBytes("ISO8859-1"), "UTF-8"); System.out.println(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
此时还有一个解决办法,即修改tomcat服务器的配置文件conf/server.xml,切记此方法在实际开发中不要使用。
阅读文档http://localhost:8080/docs/config/http.html,可发现两个属性:
URIEncoding和
useBodyEncodingForURI。
在tomcat服务器的配置文件conf/server.xml中找到如下代码,并添加属性
URIEncoding=UTF-8或者
useBodyEncodingForURI=true。
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
由于我使用的是tomcat8,所以在不指定属性
URIEncoding=UTF-8的情况下,默认就是UTF-8,所以不用修改。
public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); System.out.println(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
以上代码输出正常,不会显示乱码。
以超链接形式传递中文参数的乱码问题
客户端想传输数据到服务器,可以通过表单提交的形式,也可以通过超链接后面加参数的形式,例如:<a href="/day06/RequestDemo4?username=中国">点点</a>
点击超链接,数据是以get的方式传输到服务器的,所以接收中文数据时也会产生中文乱码问题,而解决中文乱码问题的方式与上述的以get方式提交表单中文数据乱码处理问题的方式一致,如下所示:
String username = request.getParameter("username"); username = new String(username.getBytes("ISO8859-1"), "UTF-8");
另外,需要提的一点就是URL地址后面如果跟了中文数据,那么中文参数最好使用URL编码进行处理,如下所示:
<a href="day06/RequestDemo4?username=<%=URLEncoder.encode('中国', 'UTF-8')%>">点点</a>
总之:超链接提交的中文,服务器想不乱码,也只能手工处理。
一道测试题
例如有如下的form表单页面:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>request接收中文参数乱码问题</title> </head> <body> <form action="/day06/RequestDemo4" method="post"> 用户名:<input type="text" name="username"><br/> <input type="submit" value="提交"> </form> </body> </html>
运行如下代码,在浏览器显示的会不会是乱码?
public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); // 只对客户机的post方式提交有效 String username = request.getParameter("username"); response.setCharacterEncoding("GBK"); response.setContentType("text/html;charset=GBK"); response.getWriter().write(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
解:不会。
因为以上代码相当于:
public class RequestDemo4 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = "中国"; response.setCharacterEncoding("GBK"); response.setContentType("text/html;charset=GBK"); response.getWriter().write(username); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
所以在浏览器显示时不会是乱码。
Request对象实现请求转发
请求转发的基本概念
请求转发:指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。请求转发的应用场景:MVC设计模式。
M
model,即javabean。
V
view,即jsp。
C
controller,即servlet。
在Servlet中实现请求转发的方式:request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
例如:请求RequestDemo5这个Servlet,RequestDemo5将请求转发到message.jsp页面。
public class RequestDemo5 extends HttpServlet { // mvc设计模式(m--model(javabean) v--view(jsp) c--controller(servlet)) protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "aaaaaaaa"; // 每一个请求都有一个request,每个的数据都存在对应的request里面,跳到jsp,jsp显示各自的数据 request.setAttribute("data", data); // request实现转发 request.getRequestDispatcher("/message.jsp").forward(request, response);; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
request对象同时也是一个域对象(Map容器),开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
message.jsp页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Request对象实现请求转发</title> </head> <body> 使用普通方式取出存储在request对象中的数据: <% String data = (String)request.getAttribute("data"); out.write(data); %><br/> 使用EL表达式取出存储在request对象中的数据: ${data } </body> </html>
运行结果如下:
请求转发的特点:
客户端只发一次请求,而服务器端有多个资源调用。
客户端浏览器地址栏没有发生变化。
request对象作为一个域对象(Map容器)使用时,主要是通过以下的四个方法来操作:
setAttribute(String name,Object o)方法,将数据作为request对象的一个属性存放到request对象中,例如:request.setAttribute(“data”, data);
getAttribute(String name)方法,获取request对象的name属性的属性值,例如:request.getAttribute(“data”);
removeAttribute(String name)方法,移除request对象的name属性,例如:request.removeAttribute(“data”);
getAttributeNames方法,获取request对象的所有属性名,返回的是一个枚举,例如:
Enumeration<String> attrNames = request.getAttributeNames();
请求重定向和请求转发的区别
一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源,称之为请求重定向。
RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect方法可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
如果传递给HttpServletResponse.sendRedirect方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。
RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。
请求转发的细节
forward方法用于将请求转发到RequestDispatcher对象封装的资源上。如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常。
例,以下代码会抛出异常:
java.lang.IllegalStateException: Cannot forward after response has been committed。
public class RequestDemo6 extends HttpServlet { 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 doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
虽然你不会写出以上愚蠢的代码,但是你会写出如下糟糕的代码,这是在所难免的。
public class RequestDemo6 extends HttpServlet { 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); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
所以要记住:每次跳转之后一定要return。
public class RequestDemo6 extends HttpServlet { 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); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(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); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
请求转发的运行流程
RequestDispatcher的include方法
include方法:RequestDispatcher.include方法用于将RequestDispatcher对象封装的资源内容作为当前响应内容的一部分包含进来,从而实现可编程的服务器端包含功能。
被包含的Servlet程序不能改变响应消息的状态码和响应头,如果它里面存在这样的语句,这些语句的执行结果将被忽略。
在WEB应用程序的根目录,新建一个public目录,然后再在此目录下新建两个jsp——head.jsp/foot.jsp。注意:用include实现页面包含,被包含页面不要出现全局架构标签。
head.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> head<br/>
foot.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> foot<br/>
RequestDemo8代码:
// 用include实现页面包含,被包含页面不要出现全局架构标签 public class RequestDemo8 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/public/head.jsp").include(request, response); response.getWriter().write("hahahahahaha<br/>"); request.getRequestDispatcher("/public/foot.jsp").include(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
web工程中URL地址的推荐写法
在JavaWeb开发中,只要是写URL地址,那么建议最好以”/”开头,也就是使用绝对路径的方式,那么这个”/”到底代表什么呢?可以用如下的方式来记忆”/”:如果”/”是给服务器用的,则代表当前的web工程,如果”/”是给浏览器用的,则代表webapps目录。“/”代表当前web工程的常见应用场景
ServletContext.getRealPath(String path)获取资源的绝对路径this.getServletContext().getRealPath("/form.html");
ServletContext.getRealPath(“/form.html”)是用来获取服务器上的某个资源,那么这个”/”就是给服务器用的,”/”此时代表的就是web工程。ServletContext.getRealPath(“/form.html”)表示的就是读取web工程下的form.html这个资源,只要明白了”/”代表的具体含义,就可以很快写出要访问的web资源的绝对路径。
在服务器端forward到其他页面。
request.getRequestDispatcher("/form.html").forward(request, response);
客户端请求某个web资源,服务器跳转到另外一个web资源,这个forward也是给服务器用的,那么这个”/”就是给服务器用的,所以此时”/”代表的就是web工程。
使用include指令或者
<jsp:include>标签引入页面。
<%@include file="/jspfragments/head.jspf" %>
<jsp:include page="/jspfragments/demo.jsp" />
此时”/”代表的都是web工程。
ServletContext.getResourceAsStream(String path)获取资源的流对象。
this.getServletContext().getResourceAsStream("/public/foot.jsp");
“/”代表webapps目录的常见应用场景
使用sendRedirect实现请求重定向。response.sendRedirect("/day06/form2.html");
服务器发送一个URL地址给浏览器,浏览器拿到URL地址之后,再去请求服务器,所以这个”/”是给浏览器使用的,此时”/”代表的就是webapps目录。“/day06/form2.html”这个地址指的就是“webapps\day06\form2.html”。
response.sendRedirect(“/项目名称/文件夹目录/页面”);这种写法是将项目名称写死在程序中的做法,不灵活,万一哪天项目名称变了,此时就得改程序,所以推荐使用下面的灵活写法:
将:
response.sendRedirect("/day06/form2.html");
这种写法改成:
response.sendRedirect(request.getContextPath()+"/index.jsp");
request.getContextPath()获取到的内容就是”/day06”,这样就比较灵活了,使用request.getContextPath()代替”/项目名称”,推荐使用这种方式,灵活方便!
使用超链接跳转。
<a href="/day06/form.html">点点</a>
这是客户端浏览器使用的超链接跳转,这个”/”是给浏览器使用的,此时”/”代表的就是webapps目录。
使用超链接访问web资源,绝对路径的写法推荐使用下面的写法改进:
<a href="${pageContext.request.contextPath}/form.html">点点</a>
这样就可以避免在路径中出现项目的名称,使用${pageContext.request.contextPath}取代”/day06”。
form表单提交。
<form action="/day06/form.html"> </form>
这是客户端浏览器将form表单提交到服务器,所以这个”/”是给浏览器使用的,此时”/”代表的就是webapps目录。
对于form表单提交中action属性绝对路径的写法,也推荐使用如下的方式改进:
<form action="${pageContext.request.contextPath}/form.html"> </form>
${pageContext.request.contextPath}得到的就是”/day06”,
${pageContext.request.contextPath}的效果等同于request.getContextPath(),两者获取到的都是”/项目名称”。
js脚本和css样式文件的引用。
<%--使用绝对路径的方式引用js脚本--%> <script type="text/javascript" src="${pageContext.request.contextPath}/js/index.js"></script> <%--${pageContext.request.contextPath}与request.getContextPath()写法是得到的效果是一样的--%> <script type="text/javascript" src="<%=request.getContextPath()%>/js/login.js"></script> <%--使用绝对路径的方式引用css样式--%> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css" type="text/css"/>
相关文章推荐
- xilium CefGlue集成包
- POJ-2031 Building a Space Station
- jsp页面通过request传值
- 搜索框使用,UISearchBarDelegate
- easyUI中文乱码
- 96. Unique Binary Search Trees
- 我所了解的MessageQueue的消息存放过程
- 滑动视图的循环滑动
- UVA-10420 List of Conquests
- iOS开发从入门到精通--UIWindow基础
- 357. Count Numbers with Unique Digits
- java序列号 SerializeUID
- aapt.exe finished with nonzero exit value 1
- 关于面试中的一二 ------------UI控件 持续更新
- AbstractQueue抽象类源码解析
- Deque接口源码解析
- 解决“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误
- codeforces 360 E - The Values You Can Make
- Buildroot-2012.08交叉编译器制作
- Queue接口源码解析