HttpServletRequest

1 HttpServletRequest概述

在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。

service方法中的request的类型是ServletRequest,

doGet/doPost方法的request的类型是HttpServletRequest,

HttpServletRequest是ServletRequest的子接口,功能和方法更加强大

 

1.1 request的运行流程

 

1.2通过抓包工具抓取Http请求

 

 

因为request代表请求,所以可以通过该对象分别获得Http请求的请求行,请求头和请求体:

 

2通过request获得请求行

1)获得客户端的请求方式:String getMethod()

2)获得请求的资源:

String getRequestURI()  绝对路径或相对路径或网络地址

StringBuffer getRequestURL() 网络地址

String getContextPath() ---web应用的名称(重要)因为项目名有可能改,所以不能写死

String getQueryString() ---- get提交url地址后的参数字符串,只有get请求才有

request.getRemoteAddr() --- 获得访问的客户端IP地址

 

例:

建一个login.jsp:

<form action="/20190111WEB/LoginServlet" method="get"> 用户名:<input type="text" name="username" /><br /> 密码:<input type="password" name="password" /><br /> <input type="submit" value="提交" /></form>

 

建一个LoginServlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取请求行中内容 //1获取请求方式 String method=request.getMethod(); System.out.println("请求方式为"+method); //2获得请求资源的相关内容 String requestURI=request.getRequestURI(); StringBuffer requestURL=request.getRequestURL(); System.out.println("URI"+requestURI); System.out.println("URL"+requestURL); //3获得web应用名称 String contextPath=request.getContextPath(); System.out.println("web应用名称"+contextPath); //4获取get方式提交的url后的参数字符串 String queryString=request.getQueryString(); System.out.println("get提交的参数"+queryString); //5获取访问者的ip地址 String ip=request.getRemoteAddr(); System.out.println("ip为"+ip); }

 

3通过request获得请求头

3.1常用方法

String getHeader(String name)

long getDateHeader(String name)

Enumeration getHeaderNames() 枚举

Enumeration getHeaders(String name)

int getIntHeader(String name)

 

例:HeaderServlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过枚举获得所有头的名称 Enumeration<String> headNames=request.getHeaderNames(); while(headNames.hasMoreElements()){ String headerName=headNames.nextElement(); String headerValue=request.getHeader(headerName); System.out.println(headerName+":"+headerValue); } }

 

3.2 referer头做防盗链

referer头的作用:获取该访问的的来源

 

例:news.jsp:

<a href="/20190111WEB/ReferServlet">某某新闻标题</a>

 

ReferServlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取请求头中的referer String referer=request.getHeader("referer"); //判断referer if(referer!=null&&referer.startsWith("http://localhost")){ response.sendRedirect("/20190111WEB/login.jsp"); }else{ //解决中文乱码 response.setContentType("text/html;charset=utf-8"); response.getWriter().write("你是盗链者,可耻"); } }

 

 

 

如果改成:(随意改)

 

 

 

4通过request获得请求体

请求体中的内容是通过post提交的请求参数,格式是:

username=zhangsan&password=123&hobby=football&hobby=basketball

key                 value

username      [zhangsan]

password       [123]

hobby            [football,basketball]

 

4.1获得请求参数方法

String getParameter(String name)

String[] getParameterValues(String name)(多选可用这个)

Map<String,String[]> getParameterMap()

  一个key对应多个value,例如多选,就可以用map

  Map集合作用:例如注册,封装成一个对象,传到后台

 

get请求方式的请求参数上述的方法一样可以获得

 

4.2中文乱码问题

1)解决post提交方式的乱码:request.setCharacterEncoding("UTF-8"); 

2)解决get提交的方式的乱码:

因为get的参数是从地址栏获得,所以一次只能解决一个字符串的中文乱码,

先获得参数,用iso8859-1编码,getbytes("iso8859-1")

再用utf-8解码:new String(byte[], "utf-8")

完整为:

parameter = new String(parameter.getbytes("iso8859-1"),"utf-8");

 

表单一般不用get提交,所以不常用

 

例:

Login.jsp:

<form action="/20190111WEB/BodyServlet" method="post"> 用户名:<input type="text" name="username" /><br /> 密码:<input type="password" name="password" /><br /> 爱好: <input type="checkbox" name="hobby" value="zq"/>足球 <input type="checkbox" name="hobby" value="lq"/>蓝球 <input type="checkbox" name="hobby" value="ppq"/>乒乓球 <input type="checkbox" name="hobby" value="pq"/>排球<br> <input type="submit" value="提交" /> </form>

 

BodyServlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //解决中文乱码-post方式提交 request.setCharacterEncoding("utf-8"); //获取request请求体的指定参数 String uesrname=request.getParameter("username"); //解决中文乱码-get方式 uesrname=new String(uesrname.getBytes("iso8859-1"),"utf-8"); String password=request.getParameter("password"); System.out.println(uesrname+":"+password); System.out.println("-------------"); //获取所有参数的map集合 Map<String,String[]> map=request.getParameterMap(); Set<String> set=map.keySet(); for(String s:set){ //获取name值 String name=s; System.out.print(name+":"); //获取value数据 String[] values=map.get(name); //遍历数组 for(String v:values){ System.out.println(v); } System.out.println("-------------"); } }

 

5 request是一个域对象

5.1方法和作用范围

request对象也是一个存储数据的区域对象,所以也具有如下方法:

setAttribute(String name, Object o)

getAttribute(String name)

removeAttribute(String name)

 

request域的作用范围:一次请求中

 

5.2 ServletContext域与Request域的生命周期比较

ServletContext:

  创建:服务器启动

  销毁:服务器关闭

  域的作用范围:整个web应用

request:

  创建:访问时(请求时)创建request

  销毁:响应结束request销毁

  域的作用范围:一次请求中

 

6 request完成请求转发

6.1方法

获得请求转发器----path是转发的地址

  RequestDispatcher getRequestDispatcher(String path)

通过转发器对象转发

  requestDispathcer.forward(ServletRequest request, ServletResponse response)

 

例:

Servlet01:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //请求转发 //设置一个值 request.setAttribute("name", "zhangsan"); //1获得转发器 RequestDispatcher dis=request.getRequestDispatcher("/Servlet02"); //因为是在项目内部,所以不用写项目名 //2调用转发方法 dis.forward(request, response); }

 

Servlet02:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name=(String)request.getAttribute("name"); response.getWriter().write("hello! "+name+",this is Servlet02..."); }

 

6.2请求转发与重定向的区别

相同点:都跳转

不同点:

1)请求转发是Request对象的,重定向是response对象的

2)重定向两次请求,转发一次请求

3)重定向地址栏的地址变化,转发地址不变

4)重新定向可以访问外部网站,转发只能访问内部资源

5)转发的性能要优于重定向(因为只请求一次)

 

需要带值,用请求转发

不需要,可以用重定向

 

6.3客户端地址与服务器端地址的写法

客户端地址:

  是客户端去访问服务器的地址,是服务器外部的地址

  所以要写上web应用名称

服务器端地址:

  服务器内部资源的跳转的地址,所以不需要写web应用的名称

 

7注册实例

1)准备数据库和表

2)建项目,分包,导入jsp页面,添加工具类(注意修改数据库名)和jdbc jar包

3)建Users实体类

4)register.jsp上添加form的action和method,表单元素加上name,必须要和Users实体类对应上

5)编写RegisterServlet

 

 1.BeanUtils工具实现自动映射封装:

map中的数据根据key与实体的属性对应关系进行封装,所在要保证jsp表单中的name和Users中的成员变量一样。

只要key的名字与实体属性的名字一样,就会自动封装到实体中

 

把两个jar包导进去

 

//创建对象

Users users=new Users();

//调用方法

BeanUtils.populate(users, map);

 

2.手动封装uid--利用工具UUID,随机生成不重复的32位字符串,但是经过java代码生成生是36位

users.setUid(UUID.randomUUID().toString());

(返回值是UUID对象,再toString成字符串)

 

6)登录错误提示信息的处理

带着值,所以用请求转发

LoginServlet中添加一个loginInfo,

Login.jsp页面中加上:

<%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo")%>

 

完整项目源码:

 (过两天贴上)

 

重点总结:

1 通过request获得请求行

request.getMethod()

request.getRequestURI()

request.getRequestURL()

request.getContextPath()

request.getRemoteAddr()

 

2 通过request获得请求头

request.getHeader(name)

 

3 通过request获得请求体

String request.getParameter(name)

Map<String,String[]> request.getParameterMap();

String[] request.getParameterValues(name);

注意:客户端发送的参数,到服务器端都是字符串

 

4 中文乱码问题

post方式:

request.setCharacterEncoding(“UTF-8”);

get方式:

parameter = new String(parameter.getBytes(“iso8859-1”),”UTF-8”);

 

5 request是一个域对象,方法和作用范围

setAttribute(String name, Object o)

getAttribute(String name)

removeAttribute(String name)

作用范围:一次请求中

 

6请求转发

request.getRequestDispatcher(转发的地址).forward(request, response);

 

7注册实例

BeanUtils工具进行对象封装

UUID工具封装uid

错误提示信息的处理

 

相关文章