Java——HTTPServletRequest的使用
HTTPServletRequest
我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的request的类型是ServletRequest,而doGet/doPost方法的request的类型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更加强大。
TomCat下Servlet的请求和响应流程
获取HTTP请求
1、获取请求行
String uri = request.getRequestURI(); // 获取uri System.out.println("uri:"+uri); // uri:/WEB152/request StringBuffer url = request.getRequestURL(); // 获取url System.out.println("url:"+url); // url:http://127.0.0.1:8080/WEB152/request String Contextpath = request.getContextPath(); // 获取当前Web应用的名称*** System.out.println("Contextpath:"+Contextpath); // Contextpath:/WEB152 String queryString = request.getQueryString(); // 获取get提交url地址后的参数字符串 System.out.println("queryString:"+queryString); // queryString:username=x5456&passwd=123
2、获取请求头
String header = request.getHeader("User-Agent"); // 获取请求头 System.out.println(header); // PostmanRuntime/7.1.1 Enumeration<String> HeaderNamesList = request.getHeaderNames(); // 相当于一个存放String类型的集合 while(HeaderNamesList.hasMoreElements()){ // Enumeration获取键值的方法 String headername = HeaderNamesList.nextElement(); String headervalue = request.getHeader(headername); System.out.println(headername+":"+headervalue); }
结果
cache-control:no-cache
postman-token:42a50d3d-827f-4b08-98da-e7cf1eee7c2a
user-agent:PostmanRuntime/7.1.1
accept:*/*
host:127.0.0.1:8080
accept-encoding:gzip, deflate
connection:keep-alive
refer头的作用
可以知道请求的来源网站,用处是:可以做防止从其他网站点击a标签,访问我们的网站
3、获取请求体(POST请求提交的参数)
请求体格式:
String username = request.getParameter("username"); // 获取单个表单值**** System.out.println(username); // 鑫哥 String[] valuelist = request.getParameterValues("hobby"); // 获取一个数组*** System.out.println(Arrays.toString(valuelist)); // [篮球, 足球] Enumeration<String> keylist = request.getParameterNames(); // 获取所有键的值,返回Enumeration集合 while (keylist.hasMoreElements()){ String k = keylist.nextElement(); System.out.println(k+":"+Arrays.toString(request.getParameterValues(k))); /* username:[鑫哥] hobby:[篮球, 足球] sex:[男] */ } Map<String,String[]> BodyMap = request.getParameterMap(); // 返回一个Map集合***** for(String key:BodyMap.keySet()){ String[] values = BodyMap.get(key); System.out.println(key+":"+Arrays.toString(values)); /* username:[鑫哥] hobby:[篮球, 足球] sex:[男] */ }
4、请求转发与request域
Servlet1.java
request.setAttribute("name","tom"); //向request域中存储数据 RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet2"); //servlet1 将请求转发给servlet2 dispatcher.forward(request,response); //执行转发的方法
Servlet2.java
Object name = request.getAttribute("name"); // 取出域数据 response.getWriter().write((String) name); // 因为request域中的数据类型不一样,所以默认是Object属性,需要强转
ServletContext域和Request域的声明周期
ServletContext域
- 创建:Web服务器启动
- 销毁:Web服务器关闭
- 域的作用范围:整个Web应用
Request域
- 创建:请求来时,创建Request对象
- 销毁:响应结束
- 域的作用范围:一次请求中
转发与重定向的区别
- 重定向两次请求,转发一次请求
- 重定向地址栏的地址变化,转发地址不变
- 重新定向可以访问外部网站 转发只能访问内部资源
- 转发的性能要优于重定向
客户端地址与服务器端地址的写法
客户端地址:
是客户端去访问服务器的地址,服务器外部的地址,特点:写上web应用名称(直接输入地址与重定向)
服务器端地址:
服务器内部资源的跳转的地址,特点:不需要写web应用的名称(转发)
示例:注册页面
注意点:
1)设置Post请求的编码
request.setCharacterEncoding("UTF-8"); //设置request的编码---只适合post方式
2)获取Map数据,将其装进JavaBean中
// 获取请求体的数据 Map<String,String[]> properties = request.getParameterMap(); // 实例化javabean对象 User user = new User(); //使用BeanUtils进行自动映射封装 //BeanUtils工作原理:将map中的数据 根据key与实体的属性的对应关系封装 //只要key的名字与实体的属性 的名字一样 就自动封装到实体中 try { BeanUtils.populate(user, properties); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } System.out.println(user); // {...}
全部代码
import java.io.IOException; import java.lang.reflect.InvocationTargetException; 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; import org.apache.commons.dbutils.QueryRunner; import com.ithiema.utils.DataSourceUtils; public class RegisterServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置request的编码---只适合post方式 request.setCharacterEncoding("UTF-8"); //get方式乱码解决 //String username = request.getParameter("username");//乱码 //先用iso8859-1编码 在使用utf-8解码 //username = new String(username.getBytes("iso8859-1"),"UTF-8"); //1、获取数据 //String username = request.getParameter("username"); //System.out.println(username); //String password = request.getParameter("password"); //..... //2、将散装的封装到javaBean //User user = new User(); //user.setUsername(username); //user.setPassword(password); //使用BeanUtils进行自动映射封装 //BeanUtils工作原理:将map中的数据 根据key与实体的属性的对应关系封装 //只要key的名字与实体的属性 的名字一样 就自动封装到实体中 Map<String, String[]> properties = request.getParameterMap(); User user = new User(); try { BeanUtils.populate(user, properties); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } //现在这个位置 user对象已经封装好了 //手动封装uid----uuid---随机不重复的字符串32位--java代码生成后是36位 user.setUid(UUID.randomUUID().toString()); //3、将参数传递给一个业务操作方法 try { regist(user); } catch (SQLException e) { e.printStackTrace(); } //4、认为注册成功跳转到登录页面 response.sendRedirect(request.getContextPath()+"/login.jsp"); } //注册的方法 public void regist(User user) throws SQLException{ //操作数据库 QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource()); String sql = "insert into user values(?,?,?,?,?,?,?,?,?,?)"; runner.update(sql,user.getUid(),user.getUsername(),user.getPassword(),user.getName(), user.getEmail(),null,user.getBirthday(),user.getSex(),null,null); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }