HTTP与request
HTTP协议
- HTTP:超文本传输协议,定义了浏览器与服务器之间数据传输的格式;简而言之,就是一种在web中传输数据的格式。
- HTTP协议组成:
- 请求报文:请求行,请求头,请求体;
- 请求行:请求报文中的第一行数据,包括请求方式,URL,协议/版本;
- 请求头:以键值对的数据格式,给服务器传输数据。常用的请求头:user-agent,cookie;
- 请求体:get请求:没有请求体;post请求:请求体传递请求参数;
- GET:向特定的资源发出请求(a href="servlet"标签/js location.href=“servlet”)
- POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改
- 响应报文:响应行,响应头,响应体;
- 请求报文:请求行,请求头,请求体;
百科:HTTP协议
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。
所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
1960年美国人TedNelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。
Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工作小组(Internet Engineering Task Force )共同合作研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP 1.1
协议版本:
HTTP/1.0,发送请求,创建一次连接,获得一个web资源,连接断开。
HTTP/1.1,发送请求,创建一次连接,获得多个web资源,连接断开。
GET和POST请求区别
GET请求:
请求行直接传递请求参数
将请求参数追加在URL后面,不安全。例如:form.html?username=jack&username=1234
URL长度限制GET请求方式的数据大小,不可以传输数据量较大或者非文本数据
请求体里面没有内容
POST请求
请求参数以请求体形式发送给服务器,数据传输安全
请求数据可以为非文本数据,可以传输数据量较大的数据
只有表单设置为method=”post”才是post请求.其他的都是get请求, 常见GET请求:地址栏直接访问、< a href=””>、< img src=””> 等
浏览器和服务器是以固定的格式进行通信的,采取的HTTP协议的请求协议。浏览器通过请求协议,将数据传送到服务器中。
request与请求数据的获取
通过request对象可以获取请求携带的数据,分别获取请求行、请求头、请求体中的数据,从而获取用户提交的数据,进行业务逻辑的处理。
什么是HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求中的所有信息都封装在这个对象中,我们通过这个对象的方法,可以获得客户这些信息。
HTTPServletRequest的作用
通过Request对象进行的常用操作:
- 获取请求行信息:请求方式,url和HTTP版本;
- 获取去请求头信息:浏览器类型,cookie等;
- 获取请求参数:url后面拼接的参数或者请求体中提交的参数;
获取请求行信息
请求行包括:请求方式,url和协议版本。HttpServletRequest对象提供了以下方法来获取这些信息。
- String getMethod():获取去请求方式的类型。
- StringBuffer getRequestURL():获取客户端发出请求完整URL。
- String getRemoteAddr():获取IP地址。
- String getProtocol():获取当前协议的名称和版本。
代码:
@WebServlet("/rowServlet")
public class RowServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求行API
//获取请求协议版本号
String protocol = request.getProtocol();
System.out.println("protocol = " + protocol);
//获取请求方式
String method = request.getMethod();
System.out.println("method = " + method);
//IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println("remoteAddr = " + remoteAddr);
//获取URL
StringBuffer requestURL = request.getRequestURL();
System.out.println("requestURL = " + requestURL);
}
}
获取请求头信息
浏览器的请求头信息是由很多:关键字:值 形式的数据组成的。HttpServletRequest对象给我们提供了两个方法用来获取请求的头信息。
- String getHeader(String name):根据请求头的k关键字获取请求头信息。
- Enumeration getHeaderNames():返回此请求包含的所有头信息的枚举。
请求头的k关键字如下表所示:
代码:
@WebServlet("/headerServlet")
public class HeaderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取请求头API
String header = request.getHeader("User-Agent");
System.out.println("header = " + header);
//获取所有key
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
System.out.println(headerNames.nextElement());
}
}
}
获取请求体(请求参数)(很重要)
学习了请求航和请求头的内容,然后就是请求体了,在请求体中,包含的是用户通过浏览器发送的请求参数,因此,我们主要学习的就是获取请求参数的方法。
回顾一下浏览器中的请求数据是怎么提交的。
get请求:提交的数据是拼接在url后面。
post请求:数据是在请求体中发送到后台的。
两者的格式都是name=value
获取请求参数的方法
- String getParameter(String name):getParameter获得指定参数名对应的值。如果没有返回null,如果有多个则获取第一个。例如username=jack。
- String[ ] getParameterValues(name):getParameterValues[ ]获取请求数据key相同的多个数据。
- request.getParameterMap():获取所有表单数据。
代码:
编写用户表单,提供表单字段:username、password、hobby、以post方式提交。
(由于没有设置utf-8,大家在提交数据时,尽量别用中文)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="requestServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
爱好:<input type="checkbox" name="hobby"value="smoking"/> 抽烟
<input type="checkbox" name="hobby"value="drinking"/> 喝酒
<input type="checkbox" name="hobby" value="tangtou"/> 烫头 <br/>
学历:<select name="education">
<option value="gaozhong">高中</option>
<option value="dazhuan">大专</option>
<option value="benke">本科</option>
</select><br>
<input type="submit"value="post提交" />
</form>
</body>
</html>
@WebServlet("/requestServlet")
public class RequestServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取用户提交的所有数据
String username=request.getParameter("username");
System.out.println("用户提交的所有数据:useranme:"+username);
String password=request.getParameter("password");
System.out.println("-------------------password:"+password);
String[] hobbies=request.getParameterValues("hobby");
System.out.println("-------------------hobby:"+Arrays.toString(hobbies));
//可以获取表单提交所有信息
Map<String,String[]> parameterMap=request.getParameterMap();
Collection<String[]> values=parameterMap.values();
for (String[] value:values){
System.out.println(Arrays.toString(value));
}
}
}
request作用域
request的生命周期
【一次请求和响应的完整流程】
1、浏览器向servlet发送请求
2、tomcat收到请求后,创建Request和Response两个对象,并将请求数据封装到request对象中,然后传递给Servlet
3、Servlet接收到请求后,调用request提供的方法。处理浏览器的请求信息,然后通过Response返回信息
4、tomcat将业务逻辑处理的结果,返回给浏览器。
5、浏览器接收到返回消息后,tomcat销毁Request和Response两个对象,同时销毁这两个对象所获得的信息。
- 创建:浏览器给服务器发送请求后,tomcat创建request对象封装请求数据;
- 销毁:服务器给浏览器响应信息结束后销毁;
特点:浏览器每次给服务器发送请求,服务器都会为这次请求创建一个request对象。
request域对象
request域对象,一个存储数据的区域对象.是把request当成一个容器来存储数据,request域存储数据主要是用于在两个servlet之间传递数据。request作为域对象,常用的方法如下:
- void setAttribute(String name,Object o):往request域中设置值。
- Object getAttribute(String name):从request域中取值。
- void removeAttribute(String name):从request域中删除值。
演示:
创建一个servlet
往request域中设置值
从request域中取值
将request域中的值移除
@WebServlet("/value")
public class ValueServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用request对象存储值
request.setAttribute("key","关晓彤");
//根据KEY 来获取值
String key = (String) request.getAttribute("key");
System.out.println("美女 = " + key);
//移除值
request.removeAttribute("key");
Object key1 = request.getAttribute("key");
if (key1==null){
System.out.println("删除成功");
}
}
}
注意:getParameter()方法和getAttribute()方法的区别
- getParameter()方法获取的是浏览器提交的数据(多是表单提交的数据);
- getAttribute()方法是获取request域中的数据(通过request.setAttribute()设置的值;
请求转发:
我们之前使用到的请求都是从页面发出,然后请求到Servlet。其实,在Servlet中。请求也可以从一个Servlet发起,然后请求到另一个Servlet或静态页面。这项技术叫做请求转发。
请求转发需要借助以下两个方法实现:
- RequestDispatcher getRequestDispatcher(String path):获取请求转发器(request对象方法)
- void forward(ServletRequest request, ServletResponse response):将请求转发到另一个资源(Servlet)上
演示:请求转发
需求:
从一个Servlet转发到另一个Servlet;
从一个Servlet转发到一个静态页面;
@WebServlet("/twoServlet")
public class TwoServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//通过request域对象设置值
//使用转发 其他servlet
req.setAttribute("name","xiaoming");
//避免代码臃肿
//获取请求转发器
req.getRequestDispatcher("/thrServlet").forward(req,resp);
}
}
@WebServlet("/thrServlet")
public class ThrServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获取数据,进行处理
String name=(String)req.getAttribute("name");
System.out.println("name="+name);
}
}
从servlet转发到html
@WebServlet("/oneServlet")
public class OneServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//静态资源
//使用转发
req.getRequestDispatcher("/one.html").forward(req,resp);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>关晓彤</h1>
</body>
</html>
转发:
- 转发是服务器内部的跳转行为;
- 从一个Servlet转发到另一个资源(静态或者动态),能够实现跳转,但是浏览器地址栏没有改变,因为对浏览器来说,本质上只有一个请求。
- 请求转发的作用:共享request域中的数据。
登录案例
需求:
- 设计登录表单页面,数据库用户表user (字段 id,userName,password),通过sql手动插入若干用户数据记录。
- 基于form表单数据提交,将客户端用户输入的账号和密码发送给服务器Servlet
- Servlet获取表单提交的账号和密码数据,基于所学的JdbcTemplate直接访问数据库t_user表,查询账号和密码是否正确
- 根据数据库查询的结果,如果账号密码错误,转发到error.html。账号密码都正确转发到success.html页面。
搭建环境:
。