JavaWeb——HTTP请求协议及request对象使用方法一点通与request登录实战案例(含BeanUtils类的使用)
1、Http请求协议概述
HTTP,Hyper Text Transfer Protocol,超文本传输协议,定义了客户端和服务器通信时,发送数据的格式。其特点是:
- 1)基于TCP/IP的高级协议;
- 2)默认端口是80;
- 3)基于请求、响应模型:一次请求对应一次响应;
- 4)无状态的:每次请求之间相对独立,不能交互数据;
【HTTP历史版本】:
- 1.0:每一次请求响应都会建立新的连接;
- 1.1:复用连接;
【请求消息数据格式】:
- 请求行:请求方式 请求url 请求协议/版本 请求方式,HTTP协议有7种请求方式,常见的有2种: *GET:请求参数在请求行中,在url后;请求的url长度有限制;不太安全; *POST:请求参数在请求体中,请求的url长度没有限制;相对安全;
- 请求头:请求头名称:请求头值 常见的请求头: *User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息,可以在服务器端获取该头信息,解决浏览器的兼容性问题; *Referer:告诉服务器,当前请求从哪里来,作用是:可以防盗链、统计工作。
- 请求空行:空行,用于分割POST请求的请求头和请求体的
- 请求体(正文):封装POST请求消息的请求参数的
2、request和response对象的原理
request对象和response对象是由服务器创建的,我们来使用他们;request对象是来获取请求消息对象,response对象是来设置响应消息数据。
3、request对象
1)request对象的继承体系结构如下: ServletRequset ——接口 | 继承 HttpServletRequest ——接口 | 实现 org.apache.catalina.connector.RequestFacade类(tomcat)
2)request对象的功能:
- 获取请求消息数据: 1、获取请求行数据(GET /4.servlet/demo4?name=zhangsan HTTP1.1) 获取请求方式-GET: String getMethod() 获取虚拟目录-/4.servlet: String getContextPath() 获取Servlet路径-/demo4: String getServletPath() 获取get请求方式参数-name=zhangsan: String getQueryString() 获取请求的URI- /4.servlet/demo4: String getRequestURI() - http://localhost/4.servlet/demo4: String getRequestURL() URL,统一资源定位符;URI,统一资源标识符 获取协议及版本-HTTP1.1: String getProtocol() 获取客户机的IP地址: String getRemoteAddr() @WebServlet("/requestDemo1") public class RequestDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String method = request.getMethod(); System.out.println(method); String contextPath = request.getContextPath(); System.out.println(contextPath); String servletPath = request.getServletPath(); System.out.println(servletPath); String queryString = request.getQueryString(); System.out.println(queryString); String requestURI = request.getRequestURI(); System.out.println(requestURI); StringBuffer requestURL = request.getRequestURL(); System.out.println(requestURL); String protocol = request.getProtocol(); System.out.println(protocol); String remoteAddr = request.getRemoteAddr(); System.out.println(remoteAddr); } }
2、获取请求头数据 通过请求头名称获取请求头的值:String getHeader(String name); 获取所有的请求头名称:Enumeration<String> getHeaderNames(); @WebServlet("/requestDemo2") public class RequestDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()){ String s = headerNames.nextElement(); String value = request.getHeader(s); System.out.println(s+"---"+value); } //user-agent头 String agent = request.getHeader("user-agent"); if(agent.contains("Chrome")){ System.out.println("谷歌来了"); }else if(agent.contains("Firefox")){ System.out.println("火狐来了"); } //referer头 String referer = request.getHeader("referer"); System.out.println(referer); //防盗链 if(referer!=null){ if(referer.contains("/4.servlet")){ System.out.println("非盗链"); }else{ System.out.println("盗链"); } } } }
3、获取请求体数据 请求体:只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数; 获取步骤:1、获取流对象 --BufferedReader getReader():获取字符输入流,只能操作字符数据; --ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据; 2、从流对象中拿数据 @WebServlet("/requestDemo3") public class RequestDemo3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedReader reader = request.getReader(); String line = null; while ((line=reader.readLine())!=null){ System.out.println(line); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
- 其他功能(重要):
1、获取请求参数通用方式:GET或POST方式均可 》String getParameter(String name):根据参数名称获取参数值; username=zhang&password=123 》String[] getParameterValues(String name):根据参数名称获取参数值的数组;hobby=1&hobby=2 》Enumeration<String> getParameterNames():获取所有请求的参数名称 》Map<String,String[]> getParameterMap():获取所有参数的map集合
@WebServlet("/requestDemo2")
public class RequestDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
String s = headerNames.nextElement();
String value = request.getHeader(s);
System.out.println(s+"---"+value);
}
//user-agent头
String agent = request.getHeader("user-agent");
if(agent.contains("Chrome")){
System.out.println("谷歌来了");
}else if(agent.contains("Firefox")){
System.out.println("火狐来了");
}
//referer头
String referer = request.getHeader("referer");
System.out.println(referer);
//防盗链
if(referer!=null){
if(referer.contains("/4.servlet")){
System.out.println("非盗链");
}else{
System.out.println("盗链");
}
}
}
}
【中文乱码问题】:get方式:tomcat8 已经将get乱码问题解决了; post方式:在获取参数前设置request的编码 ,request.setCharacterEncoding("utf-8");
2、请求转发:一种在服务器内部的资源跳转方式,步骤: 》通过request对象和以前请求转发器对象:RequestDispatcher getRequestDispatcher(String path); 》使用该对象进行转发:forward(ServletRequest request, ServletResponse response);
@WebServlet("/requestDemo4")
public class RequestDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("requestDemo4被访问了");
//转发到demo5资源
request.getRequestDispatcher("/requestDemo5").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
请求转发的特点:
- 浏览器地址栏路径不发生变化;
- 只能转发到当前服务器内部内部资源中;
- 转发是一次请求;
3、共享数据: 域对象:一个有作用范围的对象,可以在范围内共享数据; request域对象:代表一次请求的范围,一般用于请求转发的多个资源中共享数据,提供的方法: 》setAttribute(String name,Object obj):存储数据; 》Object getAttribute(String name):通过键获取值; 》void removeAttribute(String name):通过键移除键值对;
4、获取ServletContext:ServletContext getServletContext();
4、request登录案例
下面通过一个登录案例,对上述的request对象相关方法进行实战,需求如下:
- 编写login.xml登录页面(username&password 两个输入框);
- 使用Druid数据库连接池技术,操作mysql,day1数据库中的user表;
- 登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您;
- 登录失败跳转到FailServlet展示:登录失败,用户名或密码错误。
对于以上需求,分析如下:
开发步骤:
- 1)创建项目,导入login1.html页面,配置文件,jar包;
- 2)创建数据库环境;
- 3)创建一个包cn.test.domain,创建User类;
- 4)创建一个包cn.test.dao,创建类UserDao,操作user数据库表;
- 5)创建cn.test.servlet.LoginServlet类,完成登录的具体逻辑;
- 6)注意login.html的form表单中action路径写法:虚拟目录+Servlet的资源路径;
- 7)编写LoginServlet、FailServlet、SuccessServlet。
代码就不往上贴了,登录案例的实战代码传送门。
5、BeanUtils的使用
以上我们在LoginServlet中封装User对象时,是一个个获取再封装的,若参数较多时就比较麻烦了,有没有简单的封装方式?这里我们介绍下一个开源工具类,BeanUtils,加完jar包(commons-beanutils-1.8.0.jar)后使用步骤如下示例:
//2、获取所有请求参数
Map<String, String[]> parameterMap = request.getParameterMap();
//3、创建user对象
User loginUser = new User();
try {
BeanUtils.populate(loginUser,parameterMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
BeanUtils就是用来封装JavaBean的,JavaBean是标准的Java类,就是用来封装数据的,定义要求如下:
- 1)类必须被public修饰;
- 2)必须提供空参的构造类;
- 3)成员变量必须使用private修饰;
- 4)提供公共setter和getter方法。
BeanUtils的几个重要方法:
- 1)setProperty():设置属性值
- 2)getProperty():获取属性值
- 3)populate(Object obj,Map map):将Map集合的键值对信息封装都对应的JavaBean对象中。
———————————————————————————————————————
本文为博主原创文章,转载请注明出处!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法