文章目录

  • HttpServletRequest概述
  • request对象和response对象的原理
  • request对象继承体系结构
  • reques获取功能
    • 1.获取请求行数据
    • 2. 获取请求头数据
    • 3. 获取请求体数据
  • reques其他功能
    • 1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
    • 2. 请求转发:一种在服务器内部的资源跳转方式
    • 3. 共享数据
    • 4. 获取ServletContext
  • 路径写法
  • 获取user-agent和referer请求头并演示兼容和盗链
  • 案例:用户登录
  • BeanUtils工具类,简化数据封装

HttpServletRequest概述

我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。service方法中的request的类型是ServletRequest,而doGet/doPost方法的request的类型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更加强大的HttpServletRequest。

request对象和response对象的原理

1. request和response对象是由服务器创建的。我们来使用它们
2. request对象是来获取请求消息,response对象是来设置响应消息

request对象和response对象的运行流程

request对象继承体系结构

ServletRequest       --  接口| 继承
HttpServletRequest  -- 接口|  实现
org.apache.catalina.connector.RequestFacade 类(tomcat)

reques获取功能

1.获取请求行数据

获取下面请求中的任意信息。
GET /ginger/request?name=zhangsan HTTP/1.1

@WebServlet("/request")
public class RequestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//http://localhost:8080/ginger/request//1. 获取请求方式:GETString method = req.getMethod();//2. 获取虚拟目录:/gingerString contextPath = req.getContextPath();//3. 获取Servlet路径:/requestString servletPath = req.getServletPath();//4. 获取get方式请求参数:name=zhangsanString queryString = req.getQueryString();//5. 获取请求URI:/ginger/requestString requestURI = req.getRequestURI();//6. 获取请求URL:http://localhost:8080/ginger/requestStringBuffer requestURL = req.getRequestURL();//7. 获取协议及版本:HTTP/1.1String protocol = req.getProtocol();//8. 获取客户机信息://0:0:0:0:0:0:0:1本机地址获取为了IPV6的IP,这现象只有在服务器和客户端都在同抄一台电脑上才会出现String remoteHost = req.getRemoteHost();String remoteUser = req.getRemoteUser();//null//0:0:0:0:0:0:0:1本机地址获取为了IPV6的IP,这现象只有在服务器和客户端都在同抄一台电脑上才会出现String remoteAddr = req.getRemoteAddr();int remotePort = req.getRemotePort();//54244}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}
}

2. 获取请求头数据

@WebServlet("/request2")
public class RequestServlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过请求头的名称获取请求头的值:Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0String header = req.getHeader("user-agent");System.out.println(header);//获取所有的请求头名称:Enumeration<String> headerNames = req.getHeaderNames();//Enumeration类似迭代器,遍历就行了。while (headerNames.hasMoreElements()){//获取所有请求头对应的信息。System.out.println(req.getHeader(headerNames.nextElement()));//获取的请求头信息//localhost:8080//Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0//text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8//zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2//gzip, deflate//keep-alive//JSESSIONID=C91DCF88358233DFDACC8954C8120A0A//1}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

3. 获取请求体数据

请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
步骤:

1. 获取流对象
BufferedReader getReader():获取字符输入流,只能操作字符数据
ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据2. 再从流对象中拿数据
@WebServlet("/request3")
public class RequestServlet3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//步骤://1. 获取流对象//BufferedReader getReader():获取字符输入流,只能操作字符数据//BufferedReader reader = req.getReader();//ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据ServletInputStream inputStream = req.getInputStream();//2. 再从流对象中拿数据//字符流获取数据/* String line= null;while ((line=reader.readLine())!=null){System.out.println(line);}*/System.out.println("-------------------------");//字节流获取数据byte[] bys=  new byte[1024*8];int len = 0;while((len=inputStream.read(bys))!=-1){System.out.println(new String(bys,0,len));//username=zhangsan&password=123456}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

reques其他功能

1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

中文乱码问题:get方式:tomcat 8 已经将get方式乱码问题解决了如果是tomcat低于8还是要解决乱码   String name = new String(name.getBytrs("ISO8859-1"),"UTF-8");post方式:会乱码解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
@WebServlet("/request4")
public class RequestServlet4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//get提交方式//1. String getParameter(String name):根据参数名称获取参数值//结果:张三String username = req.getParameter("username");//2. String[] getParameterValues(String name):根据参数名称获取参数值的数组//结果:疾风剑豪 影流之主String[] hobbys = req.getParameterValues("hobby");for (String hobby : hobbys) { System.out.println(hobby); }//3. Enumeration<String> getParameterNames():获取所有请求的参数名称//结果:host  user-agent  accept  accept-language accept-encoding  connection  referer cookie  upgrade-insecure-requestsEnumeration<String> headerNames = req.getHeaderNames();//遍历获取到的参数名称数组while (headerNames.hasMoreElements()) { System.out.println(headerNames.nextElement()); }//4. Map<String,String[]> getParameterMap():获取所有参数的map集合。//结果:username:张三   password:1234567    hobby:格雷福斯 疾风剑豪 影流之主Map<String, String[]> parameterMap = req.getParameterMap();//获取键值对对象集合并遍历for (Map.Entry<String, String[]> me : parameterMap.entrySet()) {String key = me.getKey();String[] values = me.getValue();System.out.print(key+":");for (String value : values) {System.out.print(value+" ");}System.out.println();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

2. 请求转发:一种在服务器内部的资源跳转方式

请求转发图解

步骤:1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
特点:1. 浏览器地址栏路径不发生变化2. 只能转发到当前服务器内部资源中。3. 转发是一次请求
@WebServlet("/request5")
public class RequestServlet5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)//RequestDispatcher requestDispatcher = req.getRequestDispatcher("/request4");//2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)//requestDispatcher.forward(req, resp);//连式编程req.getRequestDispatcher("/request4").forward(req,resp );}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

结果:

转发到了demo04........

3. 共享数据

域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

@WebServlet("/request6")
public class RequestServlet6 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1. void setAttribute(String name,Object obj):存储数据req.setAttribute("11111","法外狂徒");req.setAttribute("22222","影流之主" );//3. void removeAttribute(String name):通过键移除键值对req.removeAttribute("22222");//转发到request5req.getRequestDispatcher("/request5").forward(req,resp );}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

从reqeust6转发到request5

@WebServlet("/request5")
public class RequestServlet5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//2. Object getAttitude(String name):通过键获取值Object obj1 = req.getAttribute("11111");Object obj2 = req.getAttribute("22222");System.out.println(obj1);System.out.println(obj2);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

结果

法外狂徒
null

4. 获取ServletContext

@WebServlet("/request7")
public class RequestServlet7 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取ServletContext两种方式ServletContext servletContext = req.getServletContext();ServletContext servletContext1 = this.getServletContext();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

路径写法

路径分类

  1. 相对路径:通过相对路径不可以确定唯一资源
      如:./index.html不以/开头,以.开头路径规则:找到当前资源和目标资源之间的相对位置关系./:当前目录../:后退一级目录
  1. 绝对路径:通过绝对路径可以确定唯一资源
     如:http://localhost:8080/ginger/response3     /ginger/response3以/开头的路径规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出给客户端浏览器使用:需要加虚拟目录(项目的访问路径)建议虚拟目录动态获取:request.getContextPath()<a> , <form> 重定向...给服务器使用:不需要加虚拟目录转发路径

相对路径和绝对路径一般都是通过需求来判断路径写法。
相对路径演示
定义一个html页面

<body><h3>相对路径就是当前资源路径相对于目标资源路径的相对位置关系</h3><p>当前资源:localhost.htmlhttp://localhost:8080/ginger/localhost.html</p><p>目标资源:/response3http://localhost:8080/ginger/response3</p><!--response3代表./response3--><a href="response3">response3</a><br><!--html/location2.html代表./html/location2.html--><a href="html/location2.html">location2.html</a></body>

并访问页面

点击response3

点击location2.html

绝对路径演示
重定向在response有演示
转发在上面有演示

获取user-agent和referer请求头并演示兼容和盗链

user-agent头应用演示

@WebServlet("/request8")
public class RequestServlet8 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//演示获取请求头数据:user-agentString agent = req.getHeader("User-Agent");if(agent.contains("Chrome")){//谷歌System.out.println("谷歌访问的......");}else if(agent.contains("Firefox")){//火狐System.out.println("火狐访问的......");}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

使用火狐访问结果:

火狐访问的......

referer头应用演示
假设这是腾讯平台

@WebServlet
public class RequestServlet9 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//演示获取请求头数据:referer表示该请求时从哪里来String referer = req.getHeader("referer");System.out.println(referer);if(referer!=null){//查看该访问连接中是否包含自己的项目路径。if (referer.contains("/ginger")) {//正常访问resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("播放电影....");} else {//盗链resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("想看电影吗?来腾讯吧...");}}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

结果:我就是输出了一个该请求是从哪里来的

http://localhost/gaoqing/

假设创建新一个模块演示,表示其它的平台。(到时候会跳转到腾讯平台)
在该模块中写一个html页面用于访问腾讯平台

访问该页面

访问结果

案例:用户登录

画图分析:

我的项目结构

dao代码

public class UserDaoImpl {private JdbcTemplate jt = new JdbcTemplate(JDBCUtils.getDaSource());public User login(User user) {try {//定义sql语句String sql = "select * from User where username=? and password=?";User u = jt.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),user.getUsername(), user.getPassword());return user;} catch (DataAccessException e) {return null;}}
}

pojo代码

public class User {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}
}

servlet代码

@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("登录失败了,用户名或者密码错误。。。。");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取用户名和密码//String username = req.getParameter("username");//String password = req.getParameter("password");//创建用户对象//User user = new User();//user.setUsername(username);//user.setPassword(password);//获取所有请求参数Map<String, String[]> map = req.getParameterMap();//使用BeanUtils简化封装User user =new  User();try {BeanUtils.populate(user,map);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}//调用dao方法UserDaoImpl udi = new UserDaoImpl();User u = udi.login(user);//根据返回User对象是否为空,转发到成功或者失败页面。if (u != null) {req.setAttribute("user", u);//转发到登录成功页面req.getRequestDispatcher("/successServlet").forward(req, resp);} else {//转发到登录失败页面req.getRequestDispatcher("/failServlet").forward(req, resp);}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}
@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {User user = (User)req.getAttribute("user");//防止中文乱码resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("尊敬的"+user.getUsername()+"恭喜你登录成功!!!!!");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}

test代码

public class UserDaoTest {@Testpublic void userDaoTest() {JdbcTemplate jt = new JdbcTemplate(JDBCUtils.getDaSource());User user = new User();user.setUsername("ginger");user.setPassword("123456");//定义sql语句String sql = "select * from User where username=? and password=?";User u = jt.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),user.getUsername(), user.getPassword());System.out.println(u);}
}

utils代码

public class JDBCUtils {private static DataSource ds;//静态代码块用于初始化数据static{try {//1.加载配置文件Properties pro =  new Properties();//使用ClassLoader加载配置文件,获取字节输入流InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");pro.load(is);//2.初始化连接池对象ds = DruidDataSourceFactory.createDataSource(pro);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}public static DataSource getDaSource() {return ds;}public  static Connection getConnection() throws SQLException {return ds.getConnection();}
}

druid.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///mydatabases
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000

html页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><!--login.html中form表单的action路径的写法--><!--虚拟目录+Servlet的资源路径--><form action="/login/loginServlet">用户名:<input type="text" placeholder="请输入用户名" name="username"><br>密码:<input type="password" placeholder="请输入密码" name="password"><br><input type="submit" value="提交"></form>
</body>
</html>

代码测试
访问页面正确输入用户名和密码

转发到登录成功页面

访问页面错误输入用户名和密码

转发到登录失败页面

BeanUtils工具类,简化数据封装

用于封装JavaBean的
1. JavaBean:标准的Java类1. 要求:1. 类必须被public修饰2. 必须提供空参的构造器3. 成员变量必须使用private修饰4. 提供公共setter和getter方法2. 功能:封装数据2. 概念:成员变量:不是属性属性:setter和getter方法截取后的产物例如:getUsername() --> Username--> username3. 方法:1. setProperty()2. getProperty()3. populate(Object obj , Map map):将map集合的键值对信息,封装到对应的JavaBean对象中

证明成员变量不是属性

public class PropertyTest {@Testpublic void propertyTest() throws InvocationTargetException, IllegalAccessException {User user = new User();//假设成员变量就是属性//根据属性设置值BeanUtils.setProperty(user,"age" ,18);System.out.println(user);//User{age=0}通过结果看出来成员变量不是属性//证明截取settr和gettr是属性//根据属性设置值BeanUtils.setProperty(user,"hahaha" ,20 );System.out.println(user);//User{age=20}通过结果看出来截取调用settr和gettr才是属性。}
}

User类

public class User {private  int age;//一般情况下都是setAget,下面写法想证明成员变量不是属性。public void setHahaha(int age){this.age = age;}//一般情况下都是getAget,下面写法想证明成员变量不是属性。public int getHahaha(){return age;}@Overridepublic String toString() {return "User{" +"age=" + age +'}';}
}

JavaEE5_Request相关推荐

最新文章

  1. ArrayList的序列化
  2. DevExpress GridControl使用(二)
  3. 这是我转贴的strcpy函数与strncpy函数的比较,其中有些错误,建议大家还是看msdn,要好的多
  4. 找出重复最多的字符php,javascript获取重复次数最多的字符_javascript技巧
  5. 微服务实战(四):服务发现的可行方案以及实践案例
  6. numpy reshape resize用法
  7. cors解决ajax跨域
  8. 在实际开发中碰到的小问题,保存数据时提示:对象必须实现 IConvertible
  9. that is why用法
  10. 【从0到1,搭建Spring Boot+RESTful API+Shiro+Mybatis+SQLServer权限系统】05、Shiro集成
  11. java打印条形码Code128C
  12. ue4 如何获取端口号_尝试在UE4.22中实现罪恶装备Xrd的卡通渲染
  13. 开启mysql远程连接
  14. 某学院软件工程复试回忆总结
  15. Fragstats计算景观格局指数——批量计算(二)
  16. ubuntu 双网卡内外网优先级设置
  17. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明)(热身赛) C-Statues 题解【dp】【动态规划】
  18. Anchor-Free系列之CornerNet: Detecting Objects as Paired Keypoints
  19. 遇到电脑任务栏卡死怎么办
  20. 扬州十日记 [明]王秀楚

热门文章

  1. 在前端中,几种常见的定位使用
  2. Linux系统移植实验---USB驱动的移植
  3. HTML总结CSS学习总结
  4. 【算法分析】分支限界法详解+范例+习题解答
  5. php之sort,php中sort函数的使用方法
  6. 员工背景调查的好处 简版
  7. 勒索软件攻击防御的9件事
  8. 简编美国近200年的强国史
  9. CF630K 【Indivisibility】
  10. win32 IOCTL学习总结