关于HttpServletRequest的方法的使用

1 HttpServletRequest的功能

HttpServletRequestJavaWeb中非常重要的一个类。它是Servletservice()方法的参数之一!所以你必须必须要掌握它!

request的功能可以分为以下几种:

l         封装了请求头数据;

l         封装了请求正文数据,如果是GET请求,那么就没有正文;

l         request是一个域对象,可以把它当成Map来添加获取数据;

l         request提供了请求转发和请求包含功能。

 

2 request获取请求头数据

String value = request.getHeader(“请求头名称”);

request对象可以用来获取请求头数据,当然,这些请求数据都是Tomcat封装到request中去的。我们在service()方法中可以直接来获取!

request与请求头相关的方法有:

l         String getHeader(String name):获取指定名称的请求头;

l         Enumeration getHeaderNames():获取所有请求头名称;

l         int getIntHeader(String name):获取值为int类型的请求头。

 

       response.setContentType("text/html;charset=utf-8");

       Enumeration names = request.getHeaderNames();

       while(names.hasMoreElements()) {

           String name = (String)names.nextElement();

           String value = request.getHeader(name);

           System.out.println(name +": " + value);

           response.getWriter().println(name +": " + value + "<br/>");

       }

 

3 request获取请求相关的其它方法

request中还提供了与请求相关的其他方法,有些方法是为了我们更加便捷的方法请求头数据而设计,有些是与请求URL相关的方法。

l         int getContentLength():获取请求正文的字节数,GET请求没有正文,没有正文返回-1

l         String getContentType():获取请求类型,如果请求是GET,那么这个方法返回null;如果是POST请求,那么默认为application/x-www-form-urlencoded,其它类型以后再学;

l         String getMethod():返回请求方法,例如:GET

l         Locale getLocale():返回当前客户端浏览器支持的Localejava.util.Locale表示国家和言语,这个东西在国际化中很有用;

l         String getCharacterEncoding():获取请求编码,如果没有setCharacterEncoding(),那么返回null。表示使用ISO-8859-1编码;

l         void setCharacterEncoding(String code):设置请求编码,只对正文有效!注意,对于GET而言,没有正文!!!所以此方法只能对POST请求中的参数有效!

l         String getContextPath():返回上下文路径,例如:/hello

l         String getQueryString():返回请求URL中的参数,例如:name=zhangSan

l         String getRequestURI():返回请求URI路径,例如:/hello/oneServlet

l         StringBuffer getRequestURL():返回请求URL路径,例如:http://localhost/hello/oneServlet,即返回除了参数以外的路径信息;

l         String getServletPath():返回Servlet路径,例如:/oneServlet

l         String getRemoteAddr():返回当前客户端的IP地址;

l         String getRemoteHost():返回当前客户端的主机名,但这个方法的实现还是获取IP地址;

l         int getRemotePort():返回客户端的端口号,每次请求都会变;

l         String getSchema():返回请求协议,例如:http

l         String getServerName():返回主机名,例如:localhost

l         int getServerPort():返回服务器端口号,例如:80

 

http://localhost:8080/hello/a/b/c/d.jsp?mame=zhangSan

   System.out.println("request.getContentLength(): " + request.getContentLength());

    System.out.println("request.getContentType(): " + request.getContentType());

    System.out.println("request.getContextPath(): " + request.getContextPath());

    System.out.println("request.getMethod(): " + request.getMethod());

    System.out.println("request.getLocale(): " + request.getLocale());

       

    System.out.println("request.getQueryString(): " + request.getQueryString());

    System.out.println("request.getRequestURI(): " + request.getRequestURI());

    System.out.println("request.getRequestURL(): " + request.getRequestURL());

    System.out.println("request.getServletPath(): " + request.getServletPath());

    System.out.println("request.getRemoteAddr(): " + request.getRemoteAddr());

    System.out.println("request.getRemoteHost(): " + request.getRemoteHost());

    System.out.println("request.getRemotePort(): " + request.getRemotePort());

    System.out.println("request.getScheme(): " + request.getScheme());

    System.out.println("request.getServerName(): " + request.getServerName());

    System.out.println("request.getServerPort(): " + request.getServerPort());

 

4 request.getRemoteAddr():封IP

  可以使用request.getRemoteAddr()方法获取客户端的IP地址,然后判断IP是否为禁用IP。这种方式可以很方便的对多次密码的用户处理。

       String ip = request.getRemoteAddr();

       System.out.println(ip);

       if(ip.equals("127.0.0.1")) {

           response.sendError(500,"您的IP已被禁止!");

       } else {

           response.getWriter().print("Hello!");

       }

 

HttpServletRequest获取参数

 

1 HttpServletRequest获取参数方法

可以使用HttpServletRequest获取客户端的请求参数,相关方法如下:

l         String getParameter(String name):通过指定名称获取参数值;

l         String[] getParameterValues(String[] name):通过指定名称获取参数值数组,有可能一个名字对应多个值,例如表单中的多个复选框使用相同的name时;

l         Enumeration getParameterNames():获取所有参数的名字;

l         Map getParameterMap():获取所有参数对应的Map,其中key为参数名,value为参数值。

 

2 传递参数的方式

传递参数的方式:GETPOST

GET

l         地址栏中直接给出参数:http://localhost/param/ParamServlet?p1=v1&p2=v2

l         超链接中给出参数:<a href=” http://localhost/param/ParamServlet?p1=v1&p2=v2”>???</a>

l         表单中给出参数:<form method=”GET” action=”ParamServlet”>…</form>

 

POST

l         表单中给出参数:<form method=”POST” action=”ParamServlet”>…</form>

 

无论是GET还是POST,获取参数的方法是相同的。

String s1 = request.getParameter(“p1”);//返回v1

String s2 = request.getParameter(“p2”);//返回v2

 

    <formaction="ParamServlet"method="post">

    <inputtype="text"name="p1"/><br/>

    <inputtype="text"name="p2"/><br/>

    <inputtype="submit"value="提交"/><br/>

    </form>

    <ahref="ParamServlet?p1=v1&p2=v2">Param</a>

       String s1 = request.getParameter("p1");

       String s2 = request.getParameter("p2");

       response.getWriter().print("p1 = " + s1 +"<br/>");

       response.getWriter().print("p2 = " + s2 +"<br/>");

       Enumeration names = request.getParameterNames();

       while(names.hasMoreElements()) {

           String name = (String)names.nextElement();

           String value = request.getParameter(name);

           System.out.println(name +" = " + value);

       }

 

 

3 多值参数

例如在注册表单中,如果让用户填写爱好,那么爱好可能就是多个。那么hobby参数就会对应多个值:

    <formaction="ParamServlet"method="post">

       上网:<inputtype="checkbox"name="hobby"value="netplay"/><br/>

       踢球:<inputtype="checkbox"name="hobby"value="football"/><br/>

       看书:<inputtype="checkbox"name="hobby"value="read"/><br/>

       编程:<inputtype="checkbox"name="hobby"value="programme"/><br/>

    <inputtype="submit"value="提交"/><br/>

    </form>

       //获取所有名为hoby的参数值

       String[] hobbies = request.getParameterValues("hobby");

       System.out.println(Arrays.toString(hobbies));

 

 

4 获取所有参数,并封装到Map

  request.getParameterMap()方法返回Map类型,对应所有参数。其中Mapkey对应参数的名字;Mapvalue对应参数的值。

    <formaction="ParamServlet"method="post">

       姓名:<inputtype="text"name="name"/><br/>

       年龄:<inputtype="text"name="age"/><br/>

       性别:<inputtype="text"name="sex"/><br/>

    <inputtype="submit"value="提交"/><br/>

    </form>

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

       Set<String> keys = map.keySet();

       for(String key : keys) {

           String[] value = map.get(key);

           System.out.println(key +" = " + value[0]);

       }

sex = male

name = zhangSan

age = 23

 

 

5 BeanUtils:使用Map创建Bean实例

我们知道,可以使用Map来创建Bean实例,我们也知道,可以把表单数据封装到Map中返回。这样我们就可以通过BeanUtils把表单数据封装成Bean实例了。但要注意的是,必须要创建表单中参数的名称与Bean的属性名相同!!!

       try {

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

           Person person = new Person();

           BeanUtils.populate(person, map);[崔1] 

           System.out.println(person);

       } catch (IllegalAccessException e) {

           thrownew RuntimeException(e);

       } catch (InvocationTargetException e) {

           thrownew RuntimeException(e);

       }

 

 

6 单值参数,也可以使用request.getParameterValues(String)获取

其实当参数的值是单个的时候,同样可以使用request.getParameterValues(String)方法来获取参数值,不过这个参数返回的值为String[],这时我们需要再去获取数组下标0的元素。

String name = request.getParameterValues(“name”)[0];

 

HttpServletRequest请求转发

 

1        HttpServletRequest可以当作Map来用

JSP一共四个域对象(多出来一个PageContext,等第八天吧!)

Servlet中有三个对象是域对象,即在不同范围内传递域变量:

l         HttpServletRequest:范围为请求,在同一请求范围内传递属性;

l         HttpSession:范围是会话,在同一会话中传递属性。当某个用户打开某一网站的第一个页面开始,直到关闭该网站的所有页面结束,这是一个会话范围;

l         ServletContext:范围是Context,即项目。在同一个项目中,只有一个ServletContext

 

今天我们要使用的是HttpServletRequest的传递属性功能。

所有域对象都有如下四个方法:

l         void setAttribute(String name, Object o):设置属性,其中name为属性值,o为属性值;

l         void removeAttribute(String name):移除指定名字的属性;

l         Object getAttribute(String name):获取指定名称的属性;

l         Enumeration getAttibuteNames():获取所有属性名称。

 

  注意,attributeparameter不同,attribute是我们自己设置的,而parameter是用户通过表单、超链接中传递过来,然后由Tomcat封装到request中的。说白一点,attribute是在服务器端组件中直接设置的,而parameter是由客户端间接设置的。

 

2 在同一Servlet中测试域方法

       String name = request.getParameter("name")[崔2] ;

       request.setAttribute("name", name)[崔3] ;

       String aName = (String)request.getAttribute("name")[崔4] ;

       System.out.println(aName);

 

3 请求转发

通常一个请求往往会涉及到多个Servlet,也就是说一个Servlet不只独立完成一个请求,那么就存在了请求转发的“故事”。例如:登录验证Servlet在完成了验证之后会把请求转发给显示主页的Servlet

下面是一段“错误的转发”:

publicclass AServletextends HttpServlet {

    protectedvoid doPost(HttpServletRequest req, HttpServletResponse resp)

           throws ServletException, IOException {

       System.out.println("AServlet的工作");

       Servlet bServlet = new BServlet();

       bServlet.service(req, resp);

    }

}

publicclass BServletextends HttpServlet {

    protectedvoid doPost(HttpServletRequest req, HttpServletResponse resp)

           throws ServletException, IOException {

       System.out.println("BServlet的工作");

    }

}

 

上面代码中,AServlet会创建BServlet对象,然后去调用BServletservice()方法。这种方式确实可以调用BServlet,但这种方法的问题就太多太多了。

l         AServlet知道的太多了,它居然知道BServlet的存在;

l         BServletAServlet创建,不在是由Tomcat管理Servlet的生命周期;

 

所以我们在AServlet中不知道BServlet的存在,在AServlet中只知道一个servletName(对应<servlet-name>),然后使用Tomcat的方式,通过servletName完成转发。

如果在AServlet中需要保存数据给BServlet,那么可以使用request.setAttribute()方法来设置,然后在BServlet中就可以通过request.getAttribute()方法获取了。

AServlet中获取请求转发器:

RequestDispatcher rd = request.getRequestDispatcher(“/BServlet”);

RequestDispatcher就是请求转发器了,获取它需要使用request对象的getRequestDispatcher()方法,该方法的参数就是BServletweb.xml文件中的配置名:<servlet-name>BServlet</servlet-name>

这只是获取了转发器,还没有转发。转发需要调用RequestDispatcher对象的forward()方法,该方法需要传递requestresponse两个参数。

       // AServlet内容

Person person = new Person();[崔5] 

       try {

           BeanUtils.populate(person, request.getParameterMap());[崔6] 

       } catch (IllegalAccessException e) {

           thrownew RuntimeException(e);

       } catch (InvocationTargetException e) {

           thrownew RuntimeException(e);

       }

       request.setAttribute("person", person);[崔7] 

       RequestDispatcher rd = request.getRequestDispatcher("/BServlet");[崔8] 

       rd.forward(request, response);[崔9] 

       // BServlet内容

Person person = (Person)request.getAttribute("person");[崔10] 

       response.getWriter().print("BServlet:" + person +"<br/>")[崔11] ;

       System.out.println("BServlet: " + person)[崔12] ;

 

 

l         一个请求;

l         在一个请求中可能会执行多个Servlet

l         多个Servlet中可以共享request

l         多个Servlet中只有最后可以用来向客户端响应;

l         其他Servlet如果响应了,有两种可能:

Ø         数据只写入到缓冲区中,没有到客户端,在转必之前,Tomcat会清空这些数据;

Ø         数据已经发送到客户端,Tomcat会抛出异常,不再转发。

n         缓冲区满了,就会自动发送到客户端;

n         调用response.flushBuffer()

n         调用PrintWriter.flush()

 

4 请求包含

请求包含与请求转发非常相似,区别在与转发时AServlet中的响应正文会被清除,只会留下BServlet中的响应正文,但请求包含会保留AServlet中的响应。

请求包含需要调用RequestDispatcher对象的include()方法。请求包含基本上与转发是相同的,区别在与请求包含时,在AServlet中存在响应正文会保留下来,而请求转发会清除AServlet所做的响应正文内容。

 

       Person person = new Person();

       try {

           BeanUtils.populate(person, request.getParameterMap());

       } catch (IllegalAccessException e) {

           thrownew RuntimeException(e);

       } catch (InvocationTargetException e) {

           thrownew RuntimeException(e);

       }

       PrintWriter out = response.getWriter();

       //转发之前的响应,不会被发送到客户端浏览器上去。

       out.println("AServlet: " + person);[崔13] 

       request.setAttribute("person", person);

       RequestDispatcher rd = request.getRequestDispatcher("/BServlet");

       rd.include(request, response);[崔14] 

       Person person = (Person)request.getAttribute("person");

       PrintWriter out = response.getWriter();

       out.print("BServlet:" + person +"<br/>");

       System.out.println("BServlet: " + person);

AServlet: Person [name=zhangSan, age=23, sex=male]

BServlet:Person [name=zhangSan, age=23, sex=male]

 

5 理解请求转发和请求包含

细心的童鞋们已经发现了,当从AServlet转发到BServlet后,在客户端的浏览器地址栏中的URL还是AServlet,而不是BServlet。也就是说,请求转发这个“故事”浏览器并不知道!!!

你可以把请求转发当作是一个请求内部调用了多个Servletservice()方法完成的,而客户端只是发送了一个请求而已。


 [崔1]使用Map中的键值为person的属性赋值。

 [崔2]获取名为name的请求参数

 [崔3]设置名为name的属性,其值是请求参数

 [崔4]获取名为name的属性。注意,因为返回值类型为Object,所以需要强转

 [崔5]创建Person实例

 [崔6]把请求参数保存到Person实例中。

 [崔7]转发前把person保存起来

 [崔8]获取转发器,要转发的目的地是BServlet

 [崔9]完成转发

 [崔10]BServlet获取AServlet中设置的数据

 [崔11]向客户端输出

 [崔12]向服务器控制台打印

 [崔13]添加响应正文内容

 [崔14]请求转发到BServlet

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章