(参考http://www.cnblogs.com/xdp-gacl/p/3798347.html 点击打开链接,以此为模板 自己做了整理、修改)
目录
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>
------------------------------------------------------------------ 我是低调的分隔线 ----------------------------------------------------------------------
吾欲之南海,一瓶一钵足矣...