JavaWeb--------HttpServletRequest & HttpServletResponse

(参考http://www.cnblogs.com/xdp-gacl/p/3798347.html 点击打开链接,以此为模板 自己做了整理、修改) 

目录

一. HttpServletRequest对象

二. HttpServletResponse对象

三. WEB工程中URL地址的推荐写法


 

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象。那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。

一. HttpServletRequest对象

1.1 HttpServletRequest对象的介绍

  HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个HttpServletRequest对象中,通过这个HttpServletRequest对象提供的方法,可以获得客户端请求的所有信息。

1.2 Request常用方法

1.2.1 Request中获得客户端信息的方法

  getRequestURL() 方法返回客户端(浏览器)发出请求时的完整URL。
  getRequestURI() 方法返回请求行中的资源名部分
(注意URL和URI 的区别)
  getQueryString() 方法返回请求行中的参数部分。

  getPathInfo() 方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
  getRemoteAddr() 方法返回发出请求的客户机的IP地址。
  getRemoteHost() 方法返回发出请求的客户机的完整主机名。
  getRemotePort() 方法返回客户机所使用的网络端口号。
  getLocalAddr() 方法返回WEB服务器的IP地址。注意LocalAddr和RemoteAddr的区别。

  getLocalName() 方法返回WEB服务器的主机名。

IP地址:为了达到通信的目的,需要给参与通信的主机一个号码,这个就是ip地址,它具有唯一性。
主机名:就是在一个特定网络范围内一个计算机的名字。
域名:  则是在因特网范围内某一个服务器的名字。

好比,一个小区里面有好多住户,IP地址相当于某个住户家的门牌号(如17栋2楼201室),主机名相当于与这个门牌号对应的人家(如张三家),域名相当于住户所处在的小区(如幸福佳园小区)

范例:通过request对象获取客户端请求信息

 1 package gacl.request.study;
 2 import java.io.IOException;
 3 import java.io.PrintWriter;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 /**
 9  * @author gacl
10  * 通过request对象获取客户端请求信息
11  */
12 public class RequestDemo01 extends HttpServlet {
13 
14     public void doGet(HttpServletRequest request, HttpServletResponse response)
15             throws ServletException, IOException {
16         /**
17          * 1.获得客户机信息
18          */
19         String requestUrl = request.getRequestURL().toString();//得到客户端请求的URL地址
20         String requestUri = request.getRequestURI();//得到客户端请求的资源
21         String queryString = request.getQueryString();//得到客户端请求的URL地址中附带的参数
22         String remoteAddr = request.getRemoteAddr();//得到来访者(客户端)的IP地址
23         String remoteHost = request.getRemoteHost();//得到来访者(客户端)的完整主机名
24         int remotePort = request.getRemotePort();//得到客户端的网络端口号
25         String remoteUser = request.getRemoteUser();
26         String method = request.getMethod();//得到请求URL地址时使用的方法
27         String pathInfo = request.getPathInfo();
28         String localAddr = request.getLocalAddr();//获取WEB服务器的IP地址
29         String localName = request.getLocalName();//获取WEB服务器的主机名
30         response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码服务器端输出到客户端浏览器
31         //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器端显示的将是乱码
32         response.setHeader("content-type", "text/html;charset=UTF-8");
33         PrintWriter out = response.getWriter();
34         out.write("获取到的客户机信息如下:");
35         out.write("<hr/>");
36         out.write("请求的URL地址:"+requestUrl);
37         out.write("<br/>");
38         out.write("请求的资源:"+requestUri);
39         out.write("<br/>");
40         out.write("请求的URL地址中附带的参数:"+queryString);
41         out.write("<br/>");
42         out.write("来访者的IP地址:"+remoteAddr);
43         out.write("<br/>");
44         out.write("来访者的主机名:"+remoteHost);
45         out.write("<br/>");
46         out.write("使用的端口号:"+remotePort);
47         out.write("<br/>");
48         out.write("remoteUser:"+remoteUser);
49         out.write("<br/>");
50         out.write("请求使用的方法:"+method);
51         out.write("<br/>");
52         out.write("pathInfo:"+pathInfo);
53         out.write("<br/>");
54         out.write("localAddr:"+localAddr);
55         out.write("<br/>");
56         out.write("localName:"+localName);
57     }
58 
59     public void doPost(HttpServletRequest request, HttpServletResponse response)
60             throws ServletException, IOException {
61         doGet(request, response);
62     }
63 
64 }

运行结果:

1.2.2 获得客户端请求头

  getHeader(string name)方法: String 
  getHeaders(String name)方法: Enumeration 

  getHeaderNames()方法

案例,通过request对象获取客户端请求头信息。代码如下:

 1 package gacl.request.study;
 2 import java.io.IOException;
 3 import java.io.PrintWriter;
 4 import java.util.Enumeration;
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 /**
10  * @author gacl
11  * 获取客户端请求头信息
12  * 客户端请求头:
13  * 
14  */
15 public class RequestDemo02 extends HttpServlet {
16 
17     public void doGet(HttpServletRequest request, HttpServletResponse response)
18             throws ServletException, IOException {
19         response.setCharacterEncoding("UTF-8");//response.setCharacterEncoding()设置服务端输出到客户端浏览器的编码方式
20         //通过设置响应头控制浏览器以UTF-8的编码显示数据
21         response.setHeader("content-type", "text/html;charset=UTF-8");//设置响应头控制浏览器端显示数据的编码格式
22         PrintWriter out = response.getWriter();
23         Enumeration<String> reqHeadInfos = request.getHeaderNames();//获取所有的请求头
24         out.write("获取到的客户端所有的请求头信息如下:");
25         out.write("<hr/>");
26         while (reqHeadInfos.hasMoreElements()) {
27             String headName = (String) reqHeadInfos.nextElement();
28             String headValue = request.getHeader(headName);//根据请求头的名字获取对应的请求头的值
29             out.write(headName+":"+headValue);
30             out.write("<br/>");
31         }
32         out.write("<br/>");
33         out.write("获取到的客户端Accept-Encoding请求头的值:");
34         out.write("<hr/>");
35         String value = request.getHeader("Accept-Encoding");//获取Accept-Encoding请求头对应的值
36         out.write(value);
37         
38         Enumeration<String> e = request.getHeaders("Accept-Encoding");
39         while (e.hasMoreElements()) {
40             String string = (String) e.nextElement();
41             System.out.println(string);
42         }
43     }
44 
45     public void doPost(HttpServletRequest request, HttpServletResponse response)
46             throws ServletException, IOException {
47         doGet(request, response);
48     }
49 
50 } 

运行结果如下:

1.2.3 获得客户端提交的数据(获得客户机请求参数)

getParameter(String)方法 (常用)
getParameterValues(String name)方法 (常用)

getParameterNames()方法 (不常用)
getParameterMap()方法 (编写框架时常用)

比如现在有如下的form表单

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
     <title>Html的Form表单元素</title>
 </head>
 <body>
 <fieldset style="width:500px;">
     <legend>Html的Form表单元素</legend>
     <!--form表单的action属性规定当提交表单时,向何处发送表单数据,method属性指明表单的提交方式,分为get和post,默认为get-->
     <form action="${pageContext.request.contextPath}/servlet/RequestDemo03" method="post">
     <!--输入文本框,SIZE表示显示长度,maxlength表示最多输入长度-->
     编  号(文本框):
     <input type="text" name="userid" value="NO." size="2" maxlength="2"><br>
     <!--输入文本框,通过value指定其显示的默认值-->
     用户名(文本框):<input type="text" name="username" value="请输入用户名"><br>
     <!--密码框,其中所有输入的内容都以密文的形式显示-->
     密  码(密码框):
     <!-- 表示的是一个空格-->
     <input type="password" name="userpass" value="请输入密码"><br>
     <!--单选按钮,通过checked指定默认选中,名称必须一样,其中value为真正需要的内容-->
     性  别(单选框):
     <input type="radio" name="sex" value="男" checked>男 
     <input type="radio" name="sex" value="女">女<br>
     <!--下拉列表框,通过<option>元素指定下拉的选项-->
     部  门(下拉框):
     <select name="dept">
         <option value="技术部">技术部</option>
         <option value="销售部" SELECTED>销售部</option>
         <option value="财务部">财务部</option>
     </select><br>
     <!--复选框,可以同时选择多个选项,名称必须一样,其中value为真正需要的内容-->
     兴  趣(复选框): 
     <input type="checkbox" name="inst" value="唱歌">唱歌 
     <input type="checkbox" name="inst" value="游泳">游泳 
     <input type="checkbox" name="inst" value="跳舞">跳舞 
     <input type="checkbox" name="inst" value="编程" checked>编程 
     <input type="checkbox" name="inst" value="上网">上网
     <br>
     <!--大文本输入框,宽度为34列,高度为5行-->
     说  明(文本域):
     <textarea name="note" cols="34" rows="5">
      </textarea>
     <br>
     <!--隐藏域,在页面上无法看到,专门用来传递参数或者保存参数-->
     <input type="hidden" name="hiddenField" value="hiddenvalue"/>
     <!--提交表单按钮,当点击提交后,所有填写的表单内容都会被传输到服务器端-->
     <input type="submit" value="提交(提交按钮)">
     <!--重置表单按钮,当点击重置后,所有表单恢复原始显示内容-->
     <input type="reset" value="重置(重置按钮)">
 </form>
 <!--表单结束-->
 </fieldset>
 </body>
 <!--完结标记-->
 </html>
 <!--完结标记-->
  

案例一,服务器端使用getParameter()方法 和 getParameterValues()方法接收表单参数,代码如下:

 1 package gacl.request.study;
 2 import java.io.IOException;
 3 import java.text.MessageFormat;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 /**
 9  * @author gacl
10  * 获取客户端通过Form表单提交上来的参数
11  */
12 public class RequestDemo03 extends HttpServlet {
13 
14     public void doGet(HttpServletRequest request, HttpServletResponse response)
15             throws ServletException, IOException {
16         //客户端是以UTF-8编码提交表单数据的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于中文数据就会产生乱码
17         request.setCharacterEncoding("UTF-8"); // request.setCharacterEncoding()设置服务器端的编码方式
18         /**
19          * 编  号(文本框):
20            <input type="text" name="userid" value="NO." size="2" maxlength="2">
21          */
22         String userid = request.getParameter("userid");//服务器端获取填写的编号,userid是文本框的名字,<input type="text" name="userid">
23         /**
24          * 用户名(文本框):<input type="text" name="username" value="请输入用户名">
25          */
26         String username = request.getParameter("username");//获取填写的用户名
27         /**
28          * 密  码(密码框):<input type="password" name="userpass" value="请输入密码">
29          */
30         String userpass = request.getParameter("userpass");//获取填写的密码
31         String sex = request.getParameter("sex");//获取选中的性别
32         String dept = request.getParameter("dept");//获取选中的部门
33         //获取选中的兴趣,因为可以选中多个值,所以获取到的值是一个字符串数组,因此需要使用getParameterValues方法来获取
34         String[] insts = request.getParameterValues("inst");
35         String note = request.getParameter("note");//获取填写的说明信息
36         String hiddenField = request.getParameter("hiddenField");//获取隐藏域的内容
37         
38         String instStr="";
39         /**
40          * 获取数组数据的技巧,可以避免insts数组为null时引发的空指针异常错误!
41          */
42         for (int i = 0; insts!=null && i < insts.length; i++) {
43             if (i == insts.length-1) {
44                 instStr+=insts[i];
45             }else {
46                 instStr+=insts[i]+",";
47             }
48         }
49         
50         String htmlStr = "<table>" +
51                             "<tr><td>填写的编号:</td><td>{0}</td></tr>" +
52                             "<tr><td>填写的用户名:</td><td>{1}</td></tr>" +
53                             "<tr><td>填写的密码:</td><td>{2}</td></tr>" +
54                             "<tr><td>选中的性别:</td><td>{3}</td></tr>" +
55                             "<tr><td>选中的部门:</td><td>{4}</td></tr>" +
56                             "<tr><td>选中的兴趣:</td><td>{5}</td></tr>" +
57                             "<tr><td>填写的说明:</td><td>{6}</td></tr>" +
58                             "<tr><td>隐藏域的内容:</td><td>{7}</td></tr>" +
59                         "</table>";
60         htmlStr = MessageFormat.format(htmlStr, userid,username,userpass,sex,dept,instStr,note,hiddenField);
61         //MessageFormat.format()重要方法
62         response.setCharacterEncoding("UTF-8");//设置服务器端以UTF-8编码输出数据到客户端
63         response.setContentType("text/html;charset=UTF-8");//设置客户端浏览器以UTF-8编码解析数据
64         response.getWriter().write(htmlStr);//输出htmlStr里面的内容到客户端浏览器显示
65     }
66 
67     public void doPost(HttpServletRequest request, HttpServletResponse response)
68             throws ServletException, IOException {
69         doGet(request, response);
70     }
71 }

案例二,在服务器端使用getParameterName()方法,接收表单参数,代码如下

1 Enumeration<String> paramNames = request.getParameterNames();//服务器端获取所有的参数名
2         while (paramNames.hasMoreElements()) {
3             String name = paramNames.nextElement();//得到参数名
4             String value = request.getParameter(name);//服务器端通过参数名获取对应的值
5             System.out.println(MessageFormat.format("{0}={1}", name,value));
6         }

案例三,如果request对象中封装的参数是一Map形式存储的,则在服务器端使用getParameterMap()方法接收表单参数,代码如下:

 1 //request对象封装的参数是以Map的形式存储的
 2         Map<String, String[]> paramMap = request.getParameterMap();//服务器端接收表单参数
 3         for(Map.Entry<String, String[]> entry :paramMap.entrySet()){
 4             String paramName = entry.getKey();
 5             String paramValue = "";
 6             String[] paramValueArr = entry.getValue();
 7             for (int i = 0; paramValueArr!=null && i < paramValueArr.length; i++) {
 8                 if (i == paramValueArr.length-1) {
 9                     paramValue+=paramValueArr[i];
10                 }else {
11                     paramValue+=paramValueArr[i]+",";
12                 }
13             }
14             System.out.println(MessageFormat.format("{0}={1}", paramName,paramValue));
15         }

1.3 request接收表单提交中文参数出现乱码的问题

1.3.1 以POST方式提交表单中文参数的乱码问题

        例如下面的form表单页面:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5   <head>
 6     <title>request接收中文参数乱码问题</title>
 7   </head>
 8   
 9   <body>
10       <form action="<%=request.getContextPath()%>/servlet/RequestDemo04" method="post">
11           用户名:<input type="text" name="userName"/>
12           <input type="submit" value="post方式提交表单"> 
13       </form>
14   </body>
15 </html>

post方式提交中文数据乱码产生的原因和解决办法:

可以看到,之所以会产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收。
由于客户端是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器也需要设置以UTF-8字符编码进行接收,要想完成此操作,服务器可以直接使用从ServletRequest接口继承而来的"setCharacterEncoding(charset)"方法进行统一的编码设置。修改后的代码如下:

1 public void doPost(HttpServletRequest request, HttpServletResponse response)
2             throws ServletException, IOException {
3         /**
4          * 客户端是以UTF-8编码传输数据到服务器端的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于中文数据就会产生乱码
5          */
6         request.setCharacterEncoding("UTF-8");
7         String userName = request.getParameter("userName");
8         System.out.println("userName:"+userName);
9 }

使用request.setCharacterEncoding("UTF-8");   设置服务器以UTF-8的编码接收数据后,此时就不会产生中文乱码问题了,如下所示:

1.3.2 以GET方式提交表单中文参数的乱码问题

        例如有如下的form表单页面:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5   <head>
 6     <title>request接收中文参数乱码问题</title>
 7   </head>
 8   
 9   <body>
10         <form action="${pageContext.request.contextPath}/servlet/RequestDemo04" method="get">
11           姓名:<input type="text" name="name"/>
12           <input type="submit" value="get方式提交表单"> 
13       </form>
14   </body>
15 </html>

那么这个中文乱码问题又该如何解决呢,是否可以通过request.setCharacterEncoding("UTF-8");  设置服务器以UTF-8的编码进行接收这种方式来解决中文乱码问题呢,注意,对于以get方式传输的中文数据,通过request.setCharacterEncoding("UTF-8");这种方式是解决不了中文乱码问题,如下所示:

get方式提交中文数据乱码产生的原因和解决办法:

对于以get方式传输的数据,request即使设置了以指定的编码接收数据也是无效的(至于为什么无效我也没有弄明白),默认的还是使用ISO8859-1这个字符编码来接收数据,客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致因此才会产生中文乱码的解决办法:在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。代码如下:

 1 public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         /**
 4          *
 5          * 对于以get方式传输的数据,request即使设置了以指定的服务器端编码接收数据也是无效的,默认的还是使用ISO8859-1这个字符编码来接收数据
 6          */
 7         String name = request.getParameter("name");//接收数据
 8         name =new String(name.getBytes("ISO8859-1"), "UTF-8") ;//获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题
 9         System.out.println("name:"+name);    
10 }

1.3.3 以超链接形式传递中文参数的乱码问题

客户端想传输数据到服务器,可以通过表单提交的形式,也可以通过超链接后面加参数的形式,例如:

<a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=徐达沛">点击</a>

点击超链接,数据是以get的方式传输到服务器的,所以接收中文数据时也会产生中文乱码问题,而解决中文乱码问题的方式与上述的以get方式提交表单中文数据乱码处理问题的方式一致。即超链接数据以get方式传输到服务器,解决中文乱码与get方式也一致。如下所示:

String name = request.getParameter("name");
name =new String(name.getBytes("ISO8859-1"), "UTF-8");

另外,需要提的一点就是URL地址后面如果跟了中文数据,那么中文参数最好使用URL编码进行处理,如下所示:

(URL编码,可以参考https://www.cnblogs.com/jerrysion/p/5522673.html URL编码参考链接 )

<a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=<%=URLEncoder.encode("徐达沛", "UTF-8")%>">点击</a><%=URLEncoder.encode("徐达沛", "UTF-8")%>">点击</a>

1.3.4 提交中文数据乱码问题总结

1.4 Request对象实现请求转发

1.4.1 请求转发的基本概念

  请求转发:指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。【服务器转发
  请求转发的应用场景:MVC设计模式
  在Servlet中实现请求转发的两种方式:
  1)通过ServletContext的getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward()方法可以实现请求转发。
例如:将请求转发的test.jsp页面

 RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp");
 reqDispatcher.forward(request, response);

    2)通过request对象提供的getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward()方法可以实现请求转发。

例如:将请求转发的test.jsp页面

request.getRequestDispatcher("/test.jsp").forward(request, response);

request对象同时也是一个域对象(Map容器),开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。

案例,请求RequestDemo06 Servlet,RequestDemo06将请求转发到test.jsp页面,代码如下:

 1 package gacl.request.study;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 public class RequestDemo06 extends HttpServlet {
10 
11     public void doGet(HttpServletRequest request, HttpServletResponse response)
12             throws ServletException, IOException {
13 
14         String data="大家好,我是孤傲苍狼,我正在总结JavaWeb";
15         /**
16          * 将数据存放到request对象中,此时把request对象当作一个Map容器来使用
17          */
18         request.setAttribute("data", data);
19         //客户端访问RequestDemo06这个Servlet后,RequestDemo06通知服务器将请求转发(forward)到test.jsp页面进行处理
20         request.getRequestDispatcher("/test.jsp").forward(request, response);
21     }
22 
23     public void doPost(HttpServletRequest request, HttpServletResponse response)
24             throws ServletException, IOException {
25         doGet(request, response);
26     }
27 }

test.jsp页面代码如下:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5   <head>
 6     <title>Request对象实现请求转发</title>
 7   </head>
 8   
 9   <body>
10       使用普通方式取出存储在request对象中的数据:
11       <h3 style="color:red;"><%=(String)request.getAttribute("data")%></h3>
12      使用EL表达式取出存储在request对象中的数据:
13      <h3 style="color:red;">${data}</h3>
14   </body>
15 </html>

request对象作为一个域对象(Map容器)使用时,主要是通过以下的四个方法来操作:

1)setAttribute(String name,Object o)方法,将数据作为request对象的一个属性存放到request对象中,例如:request.setAttribute("data", data);
2)getAttribute(String name)方法,获取request对象的name属性的属性值,例如:request.getAttribute("data");
3)removeAttribute(String name)方法,移除request对象的name属性,例如:request.removeAttribute("data");
4)getAttributeNames()方法,获取request对象的所有属性名,返回的是一个,例如:Enumeration<String> attrNames = request.getAttributeNames();

1.4.2 请求转发和请求重定向的区别

一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发/307。request对象实现转发。

一个web资源收到客户端请求后,通知客户端(浏览器)去访问另外一个web资源进行处理,称之为请求重定向/302。response对象实现重定向。

forward()和redirect()的区别:

1)从地址栏显示来说
forward(): 是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器。浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址。
redirect(): 是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的URL.
2)从数据共享来说
forward(): 转发页面和转发到的页面可以共享request里面的数据。
redirect(): 不能共享数据。
3)从运用地方来说
forward(): 一般用于用户登陆的时候,根据角色转发到相应的模块。
redirect(): 一般用于用户注销登陆时,返回主页面和跳转到其它的网站等。
4)从效率来说
forward(): 高。
redirect(): 低。

二. HttpServletResponse对象

2.1 HttpServletResponse对象的介绍

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。

2.2 HttpServletResponse对象的常见应用

2.2.1 使用OutputStream流向客户端浏览器输出中文数据

使用OutputStream流输出中文注意问题:

在服务器端,数据是以哪种码表输出的,那么就要控制客户端浏览器以相应的码表打开,比如:outputStream.write("中国".getBytes("UTF-8")); 使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出,此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?可以通过设置响应头控制浏览器的行为,例如:response.setHeader("content-type", "text/html;charset=UTF-8"); 通过设置响应头控制浏览器以UTF-8的编码显示数据。

案例,使用OutputStream流向客户端浏览器输出"中国"这两个汉字。代码如下:

 1 package gacl.response.study;
 2 
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServlet;
 7 import javax.servlet.http.HttpServletRequest;
 8 import javax.servlet.http.HttpServletResponse;
 9 
10 public class ResponseDemo01 extends HttpServlet {
11 
12     private static final long serialVersionUID = 4312868947607181532L;
13 
14     public void doGet(HttpServletRequest request, HttpServletResponse response)
15             throws ServletException, IOException {
16         outputChineseByOutputStream(response);//使用OutputStream流输出中文
17     }
18     
19     /**
20      * 使用OutputStream流输出中文
21      * @param request
22      * @param response
23      * @throws IOException 
24      */
25     public void outputChineseByOutputStream(HttpServletResponse response) throws IOException{
26         /**使用OutputStream输出中文注意问题:
27          * 在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,
28          * 比如:outputStream.write("中国".getBytes("UTF-8"));//使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出
29          * 此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?
30          * 可以通过设置响应头控制浏览器的行为,例如:
31          * response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据
32          */
33         String data = "中国";
34         OutputStream outputStream = response.getOutputStream();//获取OutputStream输出流
35         response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
36         /**
37          * data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,
38          * 如果是中文的操作系统环境,默认就是查找查GB2312的码表,
39          * 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字
40          * 比如: "中"在GB2312的码表上对应的数字是98
41          *         "国"在GB2312的码表上对应的数字是99
42          */
43         /**
44          * getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表
45          */
46         byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
47         outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组
48     }
49 
50     public void doPost(HttpServletRequest request, HttpServletResponse response)
51             throws ServletException, IOException {
52         doGet(request, response);
53     }
54 
55 }

2.2.2 使用PrintWriter流向客户端浏览器输出中文数据

使用PrintWriter流输出中文注意问题:
在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒,如下:

案例,使用PrintWriter流向客户端浏览器输出"中国"这两个汉字。代码如下:

 1 package gacl.response.study;
 2 
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 import java.io.PrintWriter;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 public class ResponseDemo01 extends HttpServlet {
12 
13     private static final long serialVersionUID = 4312868947607181532L;
14 
15     public void doGet(HttpServletRequest request, HttpServletResponse response)
16             throws ServletException, IOException {
17         outputChineseByPrintWriter(response);//使用PrintWriter流输出中文
18     }
19 
20     /**
21      * 使用PrintWriter流输出中文
22      * @param request
23      * @param response
24      * @throws IOException 
25      */
26     public void outputChineseByPrintWriter(HttpServletResponse response) throws IOException{
27         String data = "中国";
28         
29         //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
30         //response.setHeader("content-type", "text/html;charset=UTF-8");
31         
32         response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
33         /**
34          * PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
35          * 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
36          */
37         PrintWriter out = response.getWriter();//获取PrintWriter输出流
38         /**
39          * 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为
40          * out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
41          * 等同于response.setHeader("content-type", "text/html;charset=UTF-8");
42          */
43         out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
44         out.write(data);//使用PrintWriter流向客户端输出字符
45     }
46     
47     public void doPost(HttpServletRequest request, HttpServletResponse response)
48             throws ServletException, IOException {
49         doGet(request, response);
50     }
51 }

当需要向浏览器输出字符数据时,使用PrintWriter比较方便,省去了将字符转换成字节数组那一步。

2.2.3 使用OutputStream或者PrintWriter向客户端浏览器输出数字

比如有如下的代码:

 1 package gacl.response.study;
 2 
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 import java.io.PrintWriter;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 public class ResponseDemo01 extends HttpServlet {
13 
14     private static final long serialVersionUID = 4312868947607181532L;
15 
16     public void doGet(HttpServletRequest request, HttpServletResponse response)
17             throws ServletException, IOException {
18         
19         outputOneByOutputStream(response);//使用OutputStream输出1到客户端浏览器
20         
21     }
22 
23     /**
24      * 使用OutputStream流输出数字1
25      * @param request
26      * @param response
27      * @throws IOException 
28      */
29     public void outputOneByOutputStream(HttpServletResponse response) throws IOException{
30         response.setHeader("content-type", "text/html;charset=UTF-8");
31         OutputStream outputStream = response.getOutputStream();
32         outputStream.write("使用OutputStream流输出数字1:".getBytes("UTF-8"));
33         outputStream.write(1);
34     }
35   }

运行的结果和我们想象中的不一样,数字1没有输出来,下面我们修改一下上面的outputOneByOutputStream方法的代码,修改后的代码如下:

 1     /**
 2      * 使用OutputStream流输出数字1
 3      * @param request
 4      * @param response
 5      * @throws IOException 
 6      */
 7     public void outputOneByOutputStream(HttpServletResponse response) throws IOException{
 8         response.setHeader("content-type", "text/html;charset=UTF-8");
 9         OutputStream outputStream = response.getOutputStream();
10         outputStream.write("使用OutputStream流输出数字1:".getBytes("UTF-8"));
11         //outputStream.write(1);
12         outputStream.write((1+"").getBytes());
13     }

1+""这一步是将数字1和一个空字符串相加,这样处理之后,数字1就变成了字符串1了,然后再将字符串1转换成字节数组使用OutputStream进行输出,此时看到的结果如下:

这次可以看到输出来的1了,这说明了一个问题:在开发过程中,如果希望服务器输出什么浏览器就能看到什么,那么在服务器端都要以字符串的形式进行输出。
如果使用PrintWriter流输出数字,那么也要先将数字转换成字符串后再输出,如下:

 1     /**
 2      * 使用PrintWriter流输出数字1
 3      * @param request
 4      * @param response
 5      * @throws IOException 
 6      */
 7     public void outputOneByPrintWriter(HttpServletResponse response) throws IOException{
 8         response.setHeader("content-type", "text/html;charset=UTF-8");
 9         response.setCharacterEncoding("UTF-8");
10         PrintWriter out = response.getWriter();//获取PrintWriter输出流
11         out.write("使用PrintWriter流输出数字1:");
12         out.write(1+"");
13     }

2.2.4 文件下载

文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载
文件下载功能的实现思路:
  1.获取要下载的文件的绝对路径
  2.获取要下载的文件名
  3.设置content-disposition响应头控制浏览器以下载的形式打开文件
  4.获取要下载的文件输入流
  5.创建数据缓冲区
  6.通过response对象获取OutputStream流
  7.将FileInputStream流写入到buffer缓冲区
  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

范例:使用Response实现文件下载

 1 package gacl.response.study;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.io.PrintWriter;
 9 import java.net.URLEncoder;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 /**
15  * @author gacl
16  * 文件下载
17  */
18 public class ResponseDemo02 extends HttpServlet {
19 
20     public void doGet(HttpServletRequest request, HttpServletResponse response)
21             throws ServletException, IOException {
22         downloadFileByOutputStream(response);//下载文件,通过OutputStream流
23     }
24 
25     /**
26      * 下载文件,通过OutputStream流
27      * @param response
28      * @throws FileNotFoundException
29      * @throws IOException
30      */
31     private void downloadFileByOutputStream(HttpServletResponse response)
32             throws FileNotFoundException, IOException {
33         //1.获取要下载的文件的绝对路径
34         String realPath = this.getServletContext().getRealPath("/download/1.JPG");
35         //2.获取要下载的文件名
36         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
37         //3.设置content-disposition响应头控制浏览器以下载的形式打开文件
38         response.setHeader("content-disposition", "attachment;filename="+fileName);
39         //4.获取要下载的文件输入流
40         InputStream in = new FileInputStream(realPath);
41         int len = 0;
42         //5.创建数据缓冲区
43         byte[] buffer = new byte[1024];
44         //6.通过response对象获取OutputStream流
45         OutputStream out = response.getOutputStream();
46         //7.将FileInputStream流写入到buffer缓冲区
47         while ((len = in.read(buffer)) > 0) {
48         //8.使用OutputStream将缓冲区的数据输出到客户端浏览器
49             out.write(buffer,0,len);
50         }
51         in.close();
52     }
53 
54     public void doPost(HttpServletRequest request, HttpServletResponse response)
55             throws ServletException, IOException {
56         doGet(request, response);
57     }
58 }

 案例,使用Response实现中文文件下载。注意:下载中文文件时,中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),否则会出现文件名乱码。代码如下:

 1 package gacl.response.study;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.io.PrintWriter;
 9 import java.net.URLEncoder;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 /**
15  * @author gacl
16  * 文件下载
17  */
18 public class ResponseDemo02 extends HttpServlet {
19 
20     public void doGet(HttpServletRequest request, HttpServletResponse response)
21             throws ServletException, IOException {
22         downloadChineseFileByOutputStream(response);//下载中文文件
23     }
24 
25     /**
26      * 下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码
27      * @param response
28      * @throws FileNotFoundException
29      * @throws IOException
30      */
31     private void downloadChineseFileByOutputStream(HttpServletResponse response)
32             throws FileNotFoundException, IOException {
33         String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径
34         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名
35         //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
36         response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
37         InputStream in = new FileInputStream(realPath);//获取文件输入流
38         int len = 0;
39         byte[] buffer = new byte[1024];
40         OutputStream out = response.getOutputStream();
41         while ((len = in.read(buffer)) > 0) {
42             out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器
43         }
44         in.close();
45     }
46     
47     public void doPost(HttpServletRequest request, HttpServletResponse response)
48             throws ServletException, IOException {
49         doGet(request, response);
50     }
51 }

文件下载注意事项:编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。
范例:使用PrintWriter流下载文件

 1 package gacl.response.study;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.io.PrintWriter;
 9 import java.net.URLEncoder;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 /**
15  * @author gacl
16  * 文件下载
17  */
18 public class ResponseDemo02 extends HttpServlet {
19 
20     public void doGet(HttpServletRequest request, HttpServletResponse response)
21             throws ServletException, IOException {
22         downloadFileByPrintWriter(response);//下载文件,通过PrintWriter流
23     }
24 
25     /**
26      * 下载文件,通过PrintWriter流,虽然也能够实现下载,但是会导致数据丢失,因此不推荐使用PrintWriter流下载文件
27      * @param response
28      * @throws FileNotFoundException
29      * @throws IOException
30      */
31     private void downloadFileByPrintWriter(HttpServletResponse response)
32             throws FileNotFoundException, IOException {
33         String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径
34         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名
35         //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码
36         response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
37         FileReader in = new FileReader(realPath);
38         int len = 0;
39         char[] buffer = new char[1024];
40         PrintWriter out = response.getWriter();
41         while ((len = in.read(buffer)) > 0) {
42             out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器
43         }
44         in.close();
45     }
46     
47     public void doPost(HttpServletRequest request, HttpServletResponse response)
48             throws ServletException, IOException {
49         doGet(request, response);
50     }
51 }

所以使用PrintWriter流处理字节数据,会导致数据丢失,这一点千万要注意,因此在编写下载文件功能时,要使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。

2.2.5 生成验证码

生成图片主要用到了一个BufferedImage类,

案例,随机生成图片。代码如下:

 1 package gacl.response.study;
 2 
 3 import java.awt.Color;
 4 import java.awt.Font;
 5 import java.awt.Graphics2D;
 6 import java.awt.image.BufferedImage;
 7 import java.io.IOException;
 8 import java.util.Random;
 9 import javax.imageio.ImageIO;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 
15 public class ResponseDemo03 extends HttpServlet {
16 
17     public void doGet(HttpServletRequest request, HttpServletResponse response)
18             throws ServletException, IOException {
19         
20         response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次
21         //1.在内存中创建一张图片
22         BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
23         //2.得到图片
24         //Graphics g = image.getGraphics();
25         Graphics2D g = (Graphics2D)image.getGraphics();
26         g.setColor(Color.WHITE);//设置图片的背景色
27         g.fillRect(0, 0, 80, 20);//填充背景色
28         //3.向图片上写数据
29         g.setColor(Color.BLUE);//设置图片上字体的颜色
30         g.setFont(new Font(null, Font.BOLD, 20));
31         g.drawString(makeNum(), 0, 20);
32         //4.设置响应头控制浏览器浏览器以图片的方式打开
33         response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
34         //5.设置响应头控制浏览器不缓存图片数据
35         response.setDateHeader("expries", -1);
36         response.setHeader("Cache-Control", "no-cache");
37         response.setHeader("Pragma", "no-cache");
38         //6.将图片写给浏览器
39         ImageIO.write(image, "jpg", response.getOutputStream());
40     }
41 
42     /**
43      * 生成随机数字
44      * @return
45      */
46     private String makeNum(){
47         Random random = new Random();
48         String num = random.nextInt(9999999)+"";
49         StringBuffer sb = new StringBuffer();
50         for (int i = 0; i < 7-num.length(); i++) {
51             sb.append("0");
52         }
53         num = sb.toString()+num;
54         return num;
55     }
56     
57     public void doPost(HttpServletRequest request, HttpServletResponse response)
58             throws ServletException, IOException {
59         doGet(request, response);
60     }
61 }

2.2.6 设置响应头控制浏览器的行为

1)设置http响应头控制浏览器禁止缓存当前文档内容     

 response.setDateHeader("expries", -1);
 response.setHeader("Cache-Control", "no-cache");
 response.setHeader("Pragma", "no-cache");

2)设置http响应头控制浏览器定时刷新网页(refresh)

response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次

3)通过response实现请求重定向

   请求重定向:指一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。
   应用场景:用户登陆,用户首先访问登录页面,登录成功后,就会跳转到某个页面,这个过程就是一个请求重定向的过程
   实现方式:response.sendRedirect(String location),即调用response对象的sendRedirect()方法实现请求重定向
 sendRedirect()方法内部的实现原理:使用response设置302状态码和设置location响应头实现重定向
例如:

  package gacl.response.study;
  import java.io.IOException;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  public class ResponseDemo04 extends HttpServlet {
  
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         /**
          * 1.调用sendRedirect方法实现请求重定向,
          * sendRedirect方法内部调用了
          * response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
          * response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
          */
         response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
         
         //2.使用response设置302状态码和设置location响应头实现重定向实现请求重定向
         //response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
         //response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
     }
 
     public void doPost(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         doGet(request, response);
     }
 }

2.3 response细节问题

  getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
  getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。  
  Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。 

  Serlvet的service()方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close()方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。

三. WEB工程中URL地址的推荐写法

在JavaWeb开发中,只要是写URL地址,那么建议最好以"/"开头,也就是使用绝对路径的方式,那么这个"/"到底代表什么呢?可以用如下的方式来记忆"/":如果"/"是给服务器用的,则代表当前的web工程;如果"/"是给浏览器用的,则代表webapps目录。

3.1  "/"代表当前web工程的常见应用场景("/"是给服务器用的)

①.ServletContext.getRealPath(String path)获取资源的绝对路径

1 /**
2 * 1.ServletContext.getRealPath("/download/1.JPG")是用来获取服务器上的某个资源,
3 * 那么这个"/"就是给服务器用的,"/"此时代表的就是web工程
4  * ServletContext.getRealPath("/download/1.JPG")表示的就是读取web工程下的download文件夹中的1.JPG这个资源
5 * 只要明白了"/"代表的具体含义,就可以很快写出要访问的web资源的绝对路径
6 */
7 this.getServletContext().getRealPath("/download/1.JPG");

②.在服务器端forward到其他页面

1 /**
2 * 2.forward
3  * 客户端请求某个web资源,服务器跳转到另外一个web资源,这个forward也是给服务器用的,
4 * 那么这个"/"就是给服务器用的,所以此时"/"代表的就是web工程
5 */
6 this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);

③.使用include指令或者<jsp:include>标签引入页面

 <%@include file="/jspfragments/head.jspf" %>
<jsp:include page="/jspfragments/demo.jsp" />

此时"/"代表的都是web工程。

3.2  "/"代表webapps目录的常见应用场景("/"是给浏览器用的)

①.使用sendRedirect实现请求重定向

response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");

服务器发送一个URL地址给浏览器,浏览器拿到URL地址之后,再去请求服务器,所以这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录,"/JavaWeb_HttpServletResponse_Study_20140615/index.jsp"这个地址指的就是"webapps\JavaWeb_HttpServletResponse_Study_20140615\index.jsp"
response.sendRedirect("/项目名称/文件夹目录/页面");这种写法是将项目名称写死在程序中的做法,不灵活,万一哪天项目名称变了,此时就得改程序,所以推荐使用下面的灵活写法:

response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");

改为

response.sendRedirect(request.getContextPath()+"/index.jsp");

request.getContextPath()获取到的内容就是"/JavaWeb_HttpServletResponse_Study_20140615",这样就比较灵活了,使用request.getContextPath()代替"/项目名称",推荐使用这种方式,灵活方便!

②.使用超链接跳转

<a href="/JavaWeb_HttpServletResponse_Study_20140615/index.jsp">跳转到首页</a>

这是客户端浏览器使用的超链接跳转,这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录。

使用超链接访问web资源,绝对路径的写法推荐使用下面的写法改进:

<a href="${pageContext.request.contextPath}/index.jsp">跳转到首页</a>

这样就可以避免在路径中出现项目的名称,使用${pageContext.request.contextPath}取代"/JavaWeb_HttpServletResponse_Study_20140615"

③.Form表单提交

<form action="/JavaWeb_HttpServletResponse_Study_20140615/servlet/CheckServlet" method="post">    
        <input type="submit" value="提交">
</form>

这是客户端浏览器将form表单提交到服务器,所以这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录。

对于form表单提交中action属性绝对路径的写法,也推荐使用如下的方式改进:

<form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
         <input type="submit" value="提交">
</form>

${pageContext.request.contextPath}得到的就是"/JavaWeb_HttpServletResponse_Study_20140615"

${pageContext.request.contextPath}的效果等同于request.getContextPath(),两者获取到的都是"/项目名称"

④.js脚本和css样式文件的引用

1  <%--使用绝对路径的方式引用js脚本--%>
2  <script type="text/javascript" src="${pageContext.request.contextPath}/js/index.js"></script>
3  <%--${pageContext.request.contextPath}与request.getContextPath()写法是得到的效果是一样的--%>
4  <script type="text/javascript" src="<%=request.getContextPath()%>/js/login.js"></script>
5  <%--使用绝对路径的方式引用css样式--%>
6  <link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css" type="text/css"/>

下面给出一个综合案例,代码如下:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5   <head>
 6     <title>"/"代表webapps目录的常见应用场景</title>
 7     <%--使用绝对路径的方式引用js脚本--%>
 8     <script type="text/javascript" src="${pageContext.request.contextPath}/js/index.js"></script>
 9     <%--${pageContext.request.contextPath}与request.getContextPath()写法是得到的效果是一样的--%>
10     <script type="text/javascript" src="<%=request.getContextPath()%>/js/login.js"></script>
11     <%--使用绝对路径的方式引用css样式--%>
12       <link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css" type="text/css"/>
13   </head>
14   
15   <body>
16       <%--form表单提交--%>
17        <form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
18            <input type="submit" value="提交">
19        </form>
20        <%--超链接跳转页面--%>
21        <a href="${pageContext.request.contextPath}/index.jsp">跳转到首页</a>
22   </body>
23 </html>

------------------------------------------------------------------ 我是低调的分隔线  ----------------------------------------------------------------------

                                                                                                                                   吾欲之南海,一瓶一钵足矣...

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值