HttpServletRequest
在创建Servlet时会重写service()方法,或doGet()/doPost(),这些方法都有两个参数,一个是代表请求的request。一个是代表响应的response。
service方法中的request的类型是ServletRequest,而doGet/doPost方法中的request是HttpServletRequest,HttpServletRequest是ServletRequest的子接口。
request的运行流程
通过抓包工具抓取Http请求
由于request是代表请求,所以可以通过该对象分别获取Http请求的请求行,请求头,请求体。
通过request获得请求行
获取客户端的请求方式:String getMethod()
获得请求的资源:String getRequestURI()
StringBuffer getRequestURL() ---主机号+端口号
String getContextPath() ---web应用的名称
String getQueryString() ---get提交url地址后的参数字符串
如:username=zhangsan&password=123
request获得客户端的一些信息
request.getRemoteAddr() ---获得访问的客户端的IP地址
package com.oracle.demo01; 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 LineServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取请求方式 String method = request.getMethod(); System.out.println("请求方式:" + method); /// 获得请求资源的相关内容 String requestURI = request.getRequestURI();//抓到什么就是什么 StringBuffer requestURL = request.getRequestURL();// 加上主机号和端口号 System.out.println(requestURI); System.out.println(requestURL); // 获取web应用的名称 String contextPath = request.getContextPath(); System.out.println("web应用的名称:" + contextPath); // 获取get方式提交的参数 String param = request.getQueryString(); System.out.println(param); // 获取客户端的IP地址 String ip = request.getRemoteAddr(); System.out.println("IP地址为:" + ip); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
运行结果如下:
通过request获得请求头
long getDateHeader(String name)
String getHeader(String name) --获取指定的头
Enumeration getHeaderNames() --获取所有的头
Enumeration getHeaders(String name)
int getIntHeader(String name)
package com.oracle.demo01; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HeaderServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取指定的头 String header = request.getHeader("User-Agent"); // 获得所有头的名称 Enumeration<String> headerName = request.getHeaderNames(); while (headerName.hasMoreElements()) { String headername = headerName.nextElement(); String headervalue = request.getHeader(headername); System.out.println(headername + ":" + headervalue); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
运行结果如下:
referer头的作用:执行该此访问的来源做防盗链
package com.oracle.demo01; 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 RefererServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 对请求的来源进行判断 String header = request.getHeader("referer"); if (header != null && header.startsWith("http://localhost:8080")) { response.setContentType("text/html;charset=UTF-8"); response.getWriter().write("马克思主义"); } else { response.getWriter().write("无耻之徒"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
通过request获得请求体
请求体中的内容是通过post提交的请求参数,格式是:
username=zhangsan&password=123&hobby=football&hobby=basketball
key----------------value
username [zhangsan]
password [123]
hobby [football,basketball]
获取请求的一些参数:
String getParameter(String name)
String[] getParameterValues(String name)
Enumeration getParameterNames()
Map<String,String[]> getParameterMap()
注:如果是get请求方式请求参数,上述方法通过适用。
解决post提交方式的乱码问题:request.setCharacerEncoding("UTF-8"); 该方式只用于post方式
解决get提交方式的乱码问题:parameter =new String(parameter.getbytes("iso8859-1"),"utf-8"); 该方式既可以用于get,也可以用于post
package com.oracle.demo01; import java.io.IOException; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegisterServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取表单中的值 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username + ":" + password); System.out.println("!!!!!!!!!!!!!!!!!!!!!!"); // 通过数组获取指定name值 String[] sex = request.getParameterValues("sex"); for (String str : sex) { System.out.println(str); } System.out.println("*******************"); // 通过map获得所有的值 Map<String, String[]> map = request.getParameterMap(); for (Map.Entry<String, String[]> entry : map.entrySet()) { // 获得对应的name值 System.out.println(entry.getKey()); //获得value值 for (String str1 : entry.getValue()) { System.out.println(str1); } System.out.println("---------------"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
request是一个域对象
request对象也是一个存储数据的区域对象,同response一样,也具有如下方法:
setAttribute(String name,Object obj)
getAttribute(String name)
removeAttribute(String name)
注:request域的作用范围:一次请求中
request完成请求转发
获得请求转发器----path是转发的地址
RequestDispatcher getRequestDispatcher(String path)
通过转发器对象转发
requestDispatcher.forward(ServletRequest request,ServletResponse response)
package com.oracle.demo02; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //将请求转发给servlet02 RequestDispatcher dispatcher=request.getRequestDispatcher("/Servlet02"); //向request中存储数据 request.setAttribute("name", "zhangsan"); //执行转发的方法 dispatcher.forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.oracle.demo02; 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 Servlet02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String value = (String) request.getAttribute("name"); response.getWriter().write("hello lzz..." + value); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
注:ServletContext域与Request域的生命周期比较
ServletContext:创建:服务器启动
销毁:服务器关闭
域的作用范围:整个web应用
Request:创建:访问时创建request
销毁:响应结束request销毁
域的作用范围:一次请求中
注:请求转发与重定向的区别
1、重定向是两次请求,转发是一次请求
2、重定向地址栏变化,转发的地址栏不变
3、重定向可以访问外部网站,转发只能访问内部资源
注:客户端地址与服务器端地址的写法
客户端地址:是客户端去访问服务器的地址,服务器外部的地址,特点:写上web应用的名称
重定向
服务器端地址:服务器内部资源的跳转地址,特点:不需要写web应用的名称
转发
案例:做一个登陆注册功能
package com.oracle.demo03; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class DButil { private DButil() { } public static Connection getConn() { try { InputStream in = DButil.class.getClassLoader().getResourceAsStream("db.properties"); Properties pro = new Properties(); pro.load(in); String url = pro.getProperty("url"); String username = pro.getProperty("username"); String password = pro.getProperty("password"); String driver = pro.getProperty("driver"); Class.forName(driver); // 获得连接 Connection conn = DriverManager.getConnection(url, username, password); return conn; } catch (Exception ex) { throw new RuntimeException(ex + "数据库连接失败"); } } public static void close(Statement sta, Connection conn) { if (sta != null) { try { sta.close(); } catch (SQLException ex) { } } if (conn != null) { try { conn.close(); } catch (SQLException ex) { } } } public static void close(ResultSet rs, Statement sta, Connection conn) { if (rs != null) { try { rs.close(); } catch (SQLException ex) { } } close(sta, conn); } } db.properties配置文件文件 driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8 username=root password=123456
package com.oracle.demo03; public class Users { private String uid; private String username; private String password; private String sex; private String hobby; @Override public String toString() { return "Users [uid=" + uid + ", username=" + username + ", password=" + password + ", sex=" + sex + ", hobby=" + hobby + "]"; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } 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; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } }
package com.oracle.demo03; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { @Override public void init() throws ServletException { int count = 0; ServletContext context = getServletContext(); context.setAttribute("count", count); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1、获取用户名和密码 String user = request.getParameter("username"); String pwd = request.getParameter("password"); System.out.println(user + "..." + pwd); // 2、从数据库验证用户名和密码是否正确 try { Connection conn = DButil.getConn(); String sql = "select * from users where username=?and pwd=?"; PreparedStatement pst = conn.prepareStatement(sql); pst.setString(1, user); pst.setString(2, pwd); ResultSet rs = pst.executeQuery(); if (rs.next()) { ServletContext context = getServletContext(); Integer count = (Integer) context.getAttribute("count"); count++; System.out.println(rs.getInt("id") + " " + rs.getString("username") + " " + rs.getString("pwd")); response.getWriter().write(rs.getInt("id") + " " + rs.getString("username") + " " + rs.getString("pwd") + "you are success login person" + " " + count); context.setAttribute("count", count); } else { request.setAttribute("loginInfo", "用户名密码或错误"); request.getRequestDispatcher("/login.jsp").forward(request, response); } DButil.close(rs, pst, conn); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.oracle.demo03; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Map; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; public class RegisteServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1、获取数据 Map<String, String[]> properties = request.getParameterMap(); Users user = new Users(); // 2、将数据封装到JavaBean // 使用BeanUtil进行自动映射封装 // 工作原理:将map中的数据根据key与实体中的属性的对应关系封装 // 只要key的名字与实体中的属性名字一样,就自动封装到实体中 // 需要导两个包 try { BeanUtils.populate(user, properties); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //手动封装一个uid--uuid---随机不重复的字符串32位,但实际的Java代码生成了36位 user.setUid(UUID.randomUUID().toString()); System.out.println(user.toString()); //调用业务方法 int row=regist(user); //跳转登陆页面 if(row>0){ response.sendRedirect(request.getContextPath()+"/login.html"); }else{ response.getWriter().write("注册失败,请重新注册"); response.sendRedirect(request.getContextPath()+"/regist.html"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public int regist(Users user){ int row=0; Connection conn=DButil.getConn(); String sql="insert into users values(?,?,?,?,?)"; try{ PreparedStatement pst=conn.prepareStatement(sql); pst.setString(1, user.getUid()); pst.setString(2, user.getUsername()); pst.setString(3, user.getPassword()); pst.setString(4, user.getSex()); pst.setString(5, user.getHobby()); row=pst.executeUpdate(); DButil.close(pst, conn); }catch(SQLException e){ e.printStackTrace(); } return row; } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <a href="/web07/RefererServlet">不断汲取马克思主义的科学智慧和理论力量</a> <form action="/web07/HeaderServlet" method="post"> <input type="text" name="username"> <input type="password"name="password"> <input type="submit" value="提交"> </form> </body> </html> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="/web07/RegisteServlet" method="post"> 用户名: <input type="text" name="username"><br> 密码: <input type="password" name="password"><br> 性别:男<input type="radio" name="sex" value="nan"> 女:<input type="radio" name="sex" value="nv"><br> 爱好:篮球<input type="checkbox" name="hobby" value="basketballl"> 足球<input type="checkbox" name="hobby" value="footballl"> 排球<input type="checkbox" name="hobby" value="volleyballl"><br> <input type="submit" value="注册"> <input type="reset" value="重置"> </form> </body> </html> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <div><%=request.getAttribute("loginInfo")%></div> <form action="/web07/HeaderServlet" method="post"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="提交"> </form> </body> </html>