目录
一.常用请求方式
1.地址栏输入
在浏览器地址栏直接输入要访问的地址即可(访问服务器的起始操作)
http://ip:port/path
2.超链接
<a href=”http://www.baidu.com”>百度</a>
3.form表单
在向服务器发送请求的过程中,当需要传输用户输入的数据,优先选用form表单的方式发送请求
<form action="com.captain.servlet/servlet02" method="post">
用户名:<input type="text" name="uname" placeholder="请输入用户名" /><br>
用户密码:<input type="password" name="upassword" placeholder="请输入密码" /><br>
<input type="submit" value="提交" />
</form>
4.ajax
通过ajax发送异步请求,实现局部刷新效果
通过jQuery中的ajax(),get(),post(),getJSON()等方法亦可发送请求
5.请求转发
通过服务器内部将请求转发一次,可以请求到其他资源
6.重定向
服务器通过给定一个新资源的地址,响应回客户端后,客户端会自动再次发送请求到新资源的地址.
二.HttpServletRequest对象
1.介绍
HttpServletRequest 对象:主要作用是用来接收客户端发送过来的请求信息;service()方法中形参接收的是HttpServletRequest 接口的实例化对象,表示该对象主要应用在HTTP 协议上,该对象是由 Tomcat 封装好传递过来。
HttpServletRequest 是 ServletRequest 的子接口,目前ServletRequest 只有HttpServletRequest 这一个接口,长远意义上,现在主要用的是http协议,如果以后出现新的协议,并且想要支持这些协议,只需要直接继承ServletRequest接口就好.
2.常用形式
1)常用方法
getRquestURL() | 获取客户端发出请求时的完整URL |
getRquestURI() | 获取请求行中的资源名称部分(项目名称开始) |
getQueryString() | 获取请求行中的参数部分 |
getMethod() | 获取客户端请求方式 |
getProtocol() | 获取HTTP版本号 |
getContextPath() | 获取webapp名字 |
2)获取请求头
getHeader(String) | 获取单个请求头内容 |
Enumeration<String>getHeaderNames() | 获取所有请求头名称的集合 |
3)获取客户端请求参数(客户端提交的数据)
getParameter(name) | 获取指定名称的参数 |
getParameterValues(String name) | 获取指定名称参数的所有值 |
getParameterNames() | 获取一个包含请求消息中的所有参数名的Enumeration对象 |
getParameterMap() | 返回一个保存了请求消息中的所有参数名称和值的Map对象 |
3.请求乱码解决
request 属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为 ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。要想解决这种乱码问题,需要设置 request 中的编码方式,告诉服务器以何种方式来解析数据。或者在接收到乱码数据以后,再通过相应的编码格式还原
Tomcat 8.0及以上版本 | get无乱码 |
post有乱码 | |
Tomcat 7.0及以下版本 | get/post都有乱码 |
方案一:
设置请求编码(这种只针对post有效,必须在接收所有数据之前设置)
request.setCharacterEncoding("UTF-8");
方案二:
new String(request.getParameter("参数名").getBytes("ISO-8859-1"),"UTF-8");
注意:一次只能处理一个参数,无论get还是post请求,皆适用,Tomcat 8.0及以上版本,get请求方式不会出现乱码
4.请求转发
请求转发,是一种服务器的行为.
当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的URL不会发生改变,得到响应后,服务器端再将响应发送到客户端,从始至终只有一个请求发出。
request.getDipatcherRequest("请求地址").forward(request,response);//达到多个资源协同响应的效果
5.request作用域对象
通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。
request 域对象中的数据在一次请求中有效,则经过请求转发,request 域中的数据依然 存在,则在请求转发的过程中可以通过 request 来传输/共享数据。
1).设置域对象内容:
request.setAttribute("user","xxx");
2).移除域对象:
request.removeAttribute("user2");
3).获取域对象的值:
String user = (String)request.getAttribute("user");
三.HttpServletResponse
1.介绍
Web 服务器收到客户端的 http 请求,会针对每一次请求,分别创建一个用于代表请求的 request 对象和代表响应的 response 对象。request 和 response 对象代表请求和响应:获取客户端数据,需要通过request 对象;向客户端输出数据,需要通过 response 对象。HttpServletResponse 的主要功能用于服务器对客户端的请求进行响应,将Web 服务器处理后的结果返回给客户端。 service()方法中形参接收的是HttpServletResponse 接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
2.常用方法
addHeader(String name,String Value) | 添加指定的键值到响应头信息中 |
containsHeader(String name) | 判断响应的头部是否被设置 |
encodeURL(String url) | 编码指定的URL |
sendError(int sc) | 使用指定状态码发送一个错误信息到客户端 |
setHeader(String name,String Value) | 设置指定响应头的值 |
setStatus(int sc) | 给当前响应设置状态 |
setContentType(String ContentType) | 设置响应的MIME类型 |
getWriter() | 获取输出字符流 |
getOutputStream() | 获取输出字节流 |
例:
public class servlet01 extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应类型
response.setContentType("text/html;charset = UTF-8");
String str= "<html><head><meta charset=\"UTF-8\"><title></title></head><body>";
str+="<form action=\'servlet02\' method=\'post\'>";
str+="用户名:<input type=\'text\' name=\'uname\' placeholder=\'请输入用户名\' /><br>";
str+="用户密码:<input type=\'password\' name=\'upassword\'placeholder=\'请输入密码\' /><br>";
str+="<input type=\'submit\' value=\'提交\' />";
str+="</form></body></html>";
response.getWriter().write(str);
}
}
3.刷新和页面自动跳转
在response 中一个比 较常用的头信息就是刷新的指令,可以完成定时刷新的功能。
resp.setHeader("refresh","2");
对于定时跳转的头信息,可以采用 HTML 的方式进行设置,HTML 本身也可以设 置头信息。(客户端跳转)
<meta http-equiv = "refresh" content = "3 ; http://www.baidu.com">
4.数据响应
接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流,有两种形式 getWriter()获取字符流(只能响应回字符);getOutputStream()获取字节流(能响应一切数据)。响应回的数据到客户端被浏览器解析。注意:两者不能同时使用。
eg1: PointWriter out = resp.getWriter();
out.write("<h1> hello world </h1>");
eg2: ServletOutputStream out = resp.getOutputStream();
out.write("<h1> hello world </h1>".getBytes());
5.乱码解决
服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
1). getWriter()的字符乱码:
getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。所以要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式,比如我们通常用的“UTF-8” resp.setCharacterEncoding("UTF-8");,此时还只完成了一半的工作,要保证数据正确显示,还需要指定客户端的解码方式resp.setHeader("content-type", "text/html;charset=UTF-8");,和服务器一致。两端指定编码后,乱码就解决了。
一句话:保证发送端和接收端的编码一致
resp.setContentType("text/html;charset=utf-8");
2). getOutputStream()字节乱码 :
当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。
指定客户端和服务器使用的编码方式一致即可 。
resp.setContentType("text/html;charset=utf-8");
总结:要想解决响应的乱码,只需要保证使用支持中文的编码格式。并且保证服务器端 和客户端使用相同的编码方式即可。
6.响应图片
客户端请求服务器的资源,在服务端获取到真实的图片资源,通过输入流读取到内存,然后通过输出流写出到客户端即可。
值得注意的是,在客户端解析资源时默认是以文本(text/html)的形式,当响应图片时 需要指定响应头信息,告知客户端响应内容为图片形式,使用一种叫做 MIME 类型的东西来指定。MIME 类型见 Tomcat 的 web.xml 文件。
<extension></extension> 扩展名的名称
<mime-type></mime-type> MIME 格式
举个栗子:
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("响应图片...");
// 设置响应类型
resp.setContentType("image/jpeg");
// 得到项目在服务器中的真实路径
String path = req.getServletContext().getRealPath("/");
// 得到图片的存放路径
String filePath = path + "/WEB-INF/jay.jpg";
// 通过路径得到file对象
File file = new File(filePath);
// 判断文件是否存在并且是一个标准文件
if (file.exists() && file.isFile()) {
// 得到输出流
ServletOutputStream out = resp.getOutputStream();
// 得到file对象的输入流
InputStream in = new FileInputStream(file);
// 输出
byte[] car = new byte[1024];
int len = 0;
while((len = in.read(car)) != -1) {
out.write(car, 0, len);
}
// 关闭资源
out.flush(); // 刷新流
in.close();
out.close();
} else {
System.out.println("文件不存在!");
}
System.out.println(path);
}
7.重定向跳转
重定向是一种服务器指导,客户端的行为。客户端发出第一个请求,被服务器接收,经过处理服务器进行响应,与此同时,服务器给客户端一个地址(下次请求的地址 resp.sendRedirect("url");),当客户端接收到响应后,立刻、马上、 自动根据服务器 给的地址进行请求的发送第二个请求,服务器接收请求并作出响应,重定向完成。从描述中可以看出重定向当中有两个请求存在,并且属于客户端行为。实现方式如下:
String name = req.getParameter("name");
System.out.println(name);
resp.sendRedirect("index.html");
请求转发和重定向的区别:(请求转发和重定向不能同时使用)
请求转发: | 重定向: |
1.只有1次请求,request作用域的数据可共享 | 1.两次请求,request作用域的数据不可共享 |
2.浏览器地址栏不发生改变 | 2.浏览器地址栏发生改变 |
3.服务器行为 | 3.客户端行为 |
4.跳转的绝对地址,可以定位到站定名后 | 4.跳转的绝对地址,可以定位到"http://"后面,可以定位到任意资源 |
四.请求时的路径问题
路径分为相对路径和绝对路径,绝对路径可简单理解为完整路径,在 web 项目中绝对路径分两种,一种是以 http://开头的,该种绝对路径已经跨域,即任何地方的资源都能访问,另一种则是从当前域名|IP|主机后的端口号开始的,不能跨域,也属于一种绝对路径。相对路径则就是相对当前资源所在路径。
1.路径问题
相对路径: 路径的前面不要加任何符号,一般情况下代表的是: "http://localhost:8080/站点名/"
绝对路径: 1、以http://开头的,完整的绝对路径,可以跨域,可以访问任何资源
2、以"/"开头,只能访问当前项目下的资源
2.请求转发和重定向的"/"代表的含义:
1、请求转发(服务端跳转):"http://localhost:8080/站点名/"
2、重定向(客户端跳转):"http://localhost:8080/"