一、HttpServletRequest概述

 

1.1、HttpServletRequest简介

  HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
  request就是将请求文本封装而成的对象,所以通过request能获得请求文本中的所有内容,请求头、请求体、请求行 。
    
 

二、详解HttpServletRequest

 

2.1、请求行

  举例:Get  http://localhost:8080/day09/servlet/req1?username=zs  http/1.1
  相关方法:
    getMethod();     获得请求方式
    getRequestURL();    返回客户端发出请求时的完整URL。
    getRequestURI();    返回请求行中的资源名部分。
    getContextPath();    当前应用的虚拟目录 
    getQueryString() ;    返回请求行中的参数部分。
//        getMethod(); 获得请求方式
// ***getRequestURL();返回客户端发出请求时的完整URL。
// ***getRequestURI(); 返回请求行中的资源名部分。
// *****getContextPath(); 当前应用的虚拟目录 /day09_01_HttpServletRequest
// getQueryString() ; 返回请求行中的参数部分。 System.out.println(request.getMethod());// GET
System.out.println(request.getRequestURL()); // http://localhost:8080/day09_01_HttpServletRequest/servlet/demo1
System.out.println(request.getRequestURI()); // /day09_01_HttpServletRequest/servlet/demo1
System.out.println(request.getContextPath()); // /day09_01_HttpServletRequest
System.out.println(request.getQueryString()); // username=tom 举例

  举例二:Get  http://localhost:6060/Web_Servlet/ServletTest3?username=faker&password=mid  http/1.1

  相关方法:

    getRequestURI();
    getRequestURL();
    getProtocol(); 
    getScheme();
    getServerName();
    getServerPort();
    getContextPath();
    getServletPath();
    getQueryString();
    getRemoteAddr(); 

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.统一资源标记符 /Web_Servlet/ServletTest3
String uri = req.getRequestURI();
System.out.println(uri);
//2.统一资源定位符 http://localhost:6060/Web_Servlet/ServletTest3
StringBuffer url = req.getRequestURL();
System.out.println(url);
//3.协议和版本 HTTP/1.1
String potocol = req.getProtocol();
System.out.println(potocol);
//4.协议 http
String scheme = req.getScheme();
System.out.println(scheme);
//5.主机(域名) localhost,如果你使用的是ip地址,就显示ip地址
String serverName = req.getServerName();
System.out.println(serverName);
//6.端口 6060(这是我自己修改了的端口,默认是8080)
int port = req. getServerPort();
System.out.println(port);
//7.发布到tomcat下的项目名称 /Web_Servlet
String contextPath = req.getContextPath();
System.out.println(contextPath);
//8.servlet路径 /ServletTest3
String servletPath = req.getServletPath();
System.out.println(servletPath);
//9.获取所有请求参数,即?之后所有东西。 username=faker&password=mid
String queryString = req.getQueryString();
System.out.println(queryString);
//10.远程主机的ip地址 0:0:0:0:0:0:0:1
String remoteAddr = req.getRemoteAddr();
System.out.println(remoteAddr); } 举例二

2.2、请求头  

  我们可以查看任意一个网页,它都是有请求头的。

  

  相关方法: 

    String getHeader(String name) 根据头名称得到头信息值

    long getDateHeader(java.lang.String name) 获得指定头内容Date

    int getIntHeader(java.lang.String name)  获得指定头内容int

    Enumeration getHeaderNames() 得到所有头信息name
    Enumeration getHeaders(String name) 根据头名称得到相同名称头信息值

  举例1:Enumeration getHeaderNames() 得到所有头信息name 

Enumeration<String> headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements()){
String key = (String)headerNames.nextElement();
String value = req.getHeader(key);
System.out.println(key+"="+value);

  结果:

    

  举例2:Enumeration getHeaders(String name) 根据头名称得到相同名称头信息值

        Enumeration<String> headers = req.getHeaders("accept-language");
while(headers.hasMoreElements()){
String key = (String)headers.nextElement();
String value = req.getHeader(key);
System.out.println(key+"==="+value); }

  结果:

    

2.3、请求体(请求正文)

  1)与表单获取相关的方法

  方法:    

    String getParameter(name)   根据表单中name属性的名,获取value属性的值方法 
    String[] getParameterValues(String name)  专为复选框取取提供的方法
    getParameterNames()   得到表单提交的所有name的方法 
    Map<String , String[]> getParameterMap()   得到表单提交的所有值的方法 //做框架用,非常实用
    getInputStream    以字节流的方式得到所有表单数据

  举例:   

<form action="/day09_01_HttpServletRequest/servlet/demo3" method="get">
用户名:<input type="text" name="userName"/><br/>
密码:<input type="password" name="pwd"/><br/>
性别:<input type="radio" name="sex" value="男" checked="checked"/>男
<input type="radio" name="sex" value="女"/>女 <br/>
爱好 :
<input type="checkbox" name="hobby" value="篮球"/>篮球
<input type="checkbox" name="hobby" value="唱歌"/>唱歌
<input type="checkbox" name="hobby" value="编码"/>编码
<br/>
所在城市:
<select name="city">
<option>------请选择------</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
</select>
<br/> <input type="submit" value="注册"/>
</form> 举例

  测试1使用方法:   

    <input type="text" name="username" />
     getParameter(name) 根据表单中name属性的名,获取value属性的值方法 
    getParameterValues(String name)专业为复选框取取提供的方法
//获取表单数据

        //根据表单中name属性的名,获取value属性的值方法
String userName = request.getParameter("userName");
String pwd = request.getParameter("pwd");
String sex = request.getParameter("sex");
String[] hobbys = request.getParameterValues("hobby"); String city = request.getParameter("city"); userName = new String(userName.getBytes("iso-8859-1"),"UTF-8");
System.out.println(userName);
System.out.println(pwd);
System.out.println(sex); for (int i = 0;hobbys!=null && i < hobbys.length; i++) {
System.out.print(hobbys[i]+"\t");
}
System.out.println(); System.out.println(city); 测试一

  测试2使用方法:

     getParameterNames() 得到表单提交的所有name的方法

    getParameterValues(String name)专业为复选框取取提供的方法

//获取所有的表单name的名子
Enumeration names = request.getParameterNames();
while(names.hasMoreElements()){
String name = (String) names.nextElement();//得到每一个name名
String[] values = request.getParameterValues(name);//根据name名,得到value值
for (int i = 0;values!=null && i < values.length; i++) {
System.out.println(name+"\t"+values[i]); 测试二

  测试3使用方法:

    getParameterMap 到表单提交的所有值的方法   //做框架用,非常实用

try {
User u = new User();
System.out.println("封装数据前:"+u);
//获取表单数据
Map<String,String[]> map = request.getParameterMap(); for (Map.Entry<String, String[]> m : map.entrySet()) {
String name = m.getKey();
String[] value = m.getValue(); //创建一属性描述器
PropertyDescriptor pd = new PropertyDescriptor(name, User.class);
//得到setter属性
Method setter = pd.getWriteMethod(); if(value.length==1){
setter.invoke(u, value[0]);//给一个值的变量赋值
}else{
setter.invoke(u, (Object)value);//相关于给复选框赋值
}
} System.out.println("封装数据后:"+u);
} catch (Exception e) {
e.printStackTrace();
} 测试三

  测试4使用方法:

    getInputStream  以字节流的方式得到所有表单数据

request.setCharacterEncoding("UTF-8");
//获取表单数据
ServletInputStream sis = request.getInputStream();
int len = 0;
byte[] b = new byte[1024];
while((len=sis.read(b))!=-1){
//System.out.println(new String(new String(b,0,len).getBytes(),"utf-8"));
System.out.println(new String(b, 0, len, "UTF-8"));
} sis.close(); 测试四

  2)与操作非表单数据相关的方法(request也是一个域对象)

  方法:

    void setAttribute(String name, Object value);
    Object getAttribute(String name);
    Void removeAttribute(String name);

  3)与请求转发相关的方法

  方法: 

    //得到请求转发或请求包含的协助对象
    RequestDispatcher getRequestDispatcher(String path)
    forward(ServletRequest request, ServletResponse response) //转发的方法
    include(ServletRequest request, ServletResponse response) //请求包含

  注意:    

    include()方法的处理流程:
      一是:如果目标组件为Servlet或JSP,就执行它们,并把它们产生的响应正文添加到源组件的响应结果中;
      如果目标组件为HTML文档,就直接把文档的内容添加到源组件的响应结果中。
      二是:返回到源组件的服务方法中,继续执行后续代码块。
    特点:
      一是:源组件与被包含的目标组件的输出数据都会被添加到响应结果中。
      二是:在目标组件中对响应状态代码或者响应头所做的修改都会被忽略。

  使用:

    //path:转发后跳转的页面,这里不管用不用"/"开头,都是以web项目根开始,因为这是请求转发,请求转发只局限与在同一个web项目下使用,所以这里一直都是从web项目根下开始的。 

    request.getRequestDispatcher(String path).forward(request,response);     

    web项目根:

      开发:G:\Workspaces\test01\WebRoot\..

      运行时:D:\java\tomcat\apache-tomcat-7.0.53\webapps\test01\..

    web站点根:

      运行时:D:\java\tomcat\apache-tomcat-7.0.53\webapps\..

    从这里可以看出,web项目根就是从该web项目名开始,所以我们请求转发时,只需要接着项目名后面需要访问的路径写就行了。

    特点:浏览器中url不会改变,也就是浏览器不知道服务器做了什么,是服务器帮我们跳转页面的,并且在转发后的页面,能够继续使用原先的request,因为是原先的request,所以request域中的属性都可以继续获取到。

  4)与编码相关的方法  

    //解决post方式编码
      request.setCharacterEncoding("UTF-8"); //告诉服务器客户端什么编码,只能处理post请求方式 
    //解决get方式编码
      String name = new String(name.getBytes(“iso-8859-1”),”UTF-8”);

三、reqeust的常见应用

 

3.1、各种表单输入项数据的获取

  text、password、radio、checkbox、file、select、textarea、 hidden
  image、button给js编程用
  请求参数的中文乱码问题 
  浏览器是什么编码就以什么编码传送数据 
  解决:request.setCharacterEncoding(“UTF-8”);//POST有效
        new String(username.getBytes(“ISO-8859-1”),“UTF-8”);//GET方式

3.2、request对象实现请求转发

  请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。
  request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
  request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。

四、HttpServletResponse概述

 

4.1、HttpServletResponse简介

  Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
  request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向容器输出数据,只需要找response对象就行了。
  HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
  
 

4.2、HttpServletResponse细节  

  getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。

  getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 会抛异常。

  Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,
  然后再与响应状态行和各响应头组合后输出到客户端。

  Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,
  如果没有,Servlet引擎将调用close方法关闭该输出流对象。

五、详解HttpServletResponse

 

5.1、响应行

  响应状态行    HTTP/1.1  200 OK

  常见的响应状态码:    

  200 OK
    一切正常,对GET和POST请求的应答文档跟在后面
  3XX  用于已经移动的文件并且充被包含在定位头信息中指定新的地址消息
    302 Found
    类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。
  4XX  用于指出客户端的错误
    404 Not Found  无法找到指定位置的资源 
  5XX   用于支持服务器错误
    500 Internal Server Error   服务器遇到了意料不到的情况,不能完成客户的请求
  方法:
    setStatus(int sc) 设置响应状态码
 

5.2、响应头

  常见的响应头  
        Accept:指示HTTP响应可以接收的文档类型集
Accept-Charset:告知客户可以接收的字符集
Accept-Encoding:所有响应的字符编码集
Content-Type:响应体的MIME类型
Content-Language:响应体的语言类型
Content-Length:响应体的长度和字节数
Expires:通知客户端过期时间,防止客户浏览器使用本地缓存副本
Cookie:包含保存到客户端的Cookie集
Redirect:提供指定重定向,可以不向浏览器输出响应内容,而是直接重新请求到另一个URL地址,实现重定向响应,即是一种自动定向。
  方法:
    setHeader(String name, String value) 设置响应头信息
    举例:
      response.setHeader(java.lang.String name, java.lang.String value) 设置指定的头,一般常用。 
    //告知浏览器使用什么码表
    response.setHeader("content-type", "text/html;charset=UTF-8");
    代替了:
   //告诉服务器应用使用UTF-8解析文本
response.setCharacterEncoding("UTF-8");
//告诉客户端要使用什么编码
response.setHeader("content-type", "text/html;charset=UTF-8");
      
      
       //告知客户端不缓存
      response.setHeader("pragma", "no-cache");
      response.setHeader("cache-control", "no-cache");
      response.setDateHeader("expires", 0);
 
      //设置每隔3秒就自动刷新一次
      response.setHeader("Refresh",3);
 

5.3、响应正文

  常用方法:

    getWrite(); 字符输出流
    getOutputStream(); 字节输出流
    setCharacterEncoding(String charset) 告知服务器使用什么编码
    setContentType(String type)
 

5.4、重定向

  1)重定向运行原理  

    重定向机制的运作流程
    第一步:用户在浏览器端输入特定URL,请求访问服务器端的某个组件
    第二步:服务器端的组件返回一个状态码为302的响应结果。
    第三步:当浏览器端接收到这种响应结果后,再立即自动请求访问另一个web组件
    第四步:浏览器端接收到来自另一个web组件的响应结果。
    HttpServeltResponse的sendRedirect(String location)用于重定向

  2)具体实现

  方式一:手动方案

    response.setStatus(302);  //状态码302就代表重定向

    response.setHeader("location","http://www.baidu.com");

  方式二:使用封装好的,通过response.sendRedirect("http://www.baidu.com");

    特点:服务器告诉浏览器要跳转的页面,是浏览器主动去跳转的页面,浏览器知道,也浏览器的地址栏中url会变,是浏览器重新发起一个请求到另外一个页面,所以request是重新发起的,跟请求转发不一样。

    注意:response.sendRedirect(path);  //

    第一种:response.sendRedirect("/test01/MyServlet01");  //使用了"/"开头,说明是从web站点根开始,所以需要写test01/MyServlet01

    第二种:response.sendRedirect("MyServlet01");  //没有使用"/"开头,说明是从web项目根开始,那么就无需写test01了。

    注意:重定向没有任何局限,可以重定向web项目内的任何路径,也可以访问别的web项目中的路径,并且这里就用"/"区分开来,如果使用了"/"开头,就说明我要重新开始定位了,不访问刚才的web项目,自己写项目名,

       如果没有使用"/"开始,那么就知道是访问刚才那个web项目下的servlet,就可以省略项目名了。就是这样来区别。

六、Response常见应用

6.1、向客户端输出中文数据

  1)用OutputStream(字节流)发送数据:
    response.getOutputStream().write(“中国”.getBytes());//以默认编码发送数据
    response.getOutputStream().write("中国".getBytes("UTF-8"));//以UTF-8编码发送数据,浏览器(默认用GB2312)会出现乱码
 
  解决办法:
    通过更改浏览器的编码方式:IE/”查看”/”编码”/”UTF-8”(不可取)
    通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知浏览器数据类型及编码
    通过meta标签模拟请求头:out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes());
    通过以下方法:response.setContentType("text/html;charset=UTF-8");
 
  2)用PrintWriter(字符流)发送数据:
    示例:response.getWriter().write(“中国” );有没有乱码?
    原因:以默认编码发送数据 ISO-8859-1(没有中国二字编码),此时会发生乱码
  解决办法:
    setCharacterEncoding(“UTF-8”);
    //更改编码为UTF-8
    response.setHead(“Context-type”,”text/html;charset=UTF-8”);
    //告诉客户端编码方式
  注意:不要忘记告诉客户端的编码方式。
    由于经常改动编码,response提供了一种更简单的方式
    response. setContentType(“text/html;charset=UTF-8”); 其作用相当于以上两条代码。

6.2、文件下载

//通过路径得到一个输入流
String path = this.getServletContext().getRealPath("/WEB-INF/classes/美女.jpg");
FileInputStream fis = new FileInputStream(path);
//创建字节输出流
ServletOutputStream sos = response.getOutputStream(); //得到要下载的文件名
String filename = path.substring(path.lastIndexOf("\\")+1); //设置文件名的编码
filename = URLEncoder.encode(filename, "UTF-8");//将不安全的文件名改为UTF-8格式 //告知客户端要下载文件
response.setHeader("content-disposition", "attachment;filename="+filename);
response.setHeader("content-type", "image/jpeg"); //执行输出操作
int len = 1;
byte[] b = new byte[1024];
while((len=fis.read(b))!=-1){
sos.write(b,0,len);
} sos.close();
fis.close(); 代码示例

6.3、生成验证码

  之后我会详细介绍

6.4、定时刷新页面

  利用Refresh刷新到其他组件。模拟注册页面,注册处理交由一个Servlet,在Servlet处理完成后,显示注册成功并转向主页。(meta也可实现)

  

转载:

https://www.cnblogs.com/zhangyinhua/p/7629221.html

【转载】Servlet中的request与response的更多相关文章

  1. JavaWeb(一)Servlet中的request与response

    一.HttpServletRequest概述 1.1.HttpServletRequest简介 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP ...

  2. servlet中的request和response

    request对象 1.什么是请求 a.浏览器向服务器发送数据就是请求. 一.request功能1--获取数据 1.获取浏览器相关的信息 getRequestURL方法 -- 返回客户端发出请求完整U ...

  3. Servlet中的request与response

    了解这方面的知识可以查看以下博客 https://www.cnblogs.com/zhangyinhua/p/7629221.html https://www.cnblogs.com/zhaojian ...

  4. JSP Servlet中的Request和Response的简单研究

    本文参考了几篇文章所得,参考目录如下: 1.http://www.cnblogs.com/guangshan/p/4198418.html 2.http://www.iteye.com/problem ...

  5. struts2中获取request、response,与android客户端进行交互(文件传递给客户端)

    用struts2作为服务器框架,与android客户端进行交互需要得到request.response对象. struts2中获取request.response有两种方法. 第一种:利用Servle ...

  6. 此时servlet中的request和我们在页面jsp中的request 是同一个request.

    在tomcat容器启动的时候,jsp页面的内置对象request,response,同样是依赖于tomcat容器中的servlet-api.jar包,这个jar包和我们在web项目中的jar包是一样的 ...

  7. springMVC中获取request和response对象的几种方式(RequestContextHolder)

    springMVC中获取request和response对象的几种方式 1.最简单方式:参数 2.加入监听器,然后在代码里面获取 原文链接:https://blog.csdn.net/weixin_4 ...

  8. LoadRunner中取Request、Response

    LoadRunner中取Request.Response LoadRunner两个“内置变量”: 1.REQUEST,用于提取完整的请求头信息. 2.RESPONSE,用于提取完整的响应头信息. 响应 ...

  9. Django中的Request和Response

    接触Django这么久了,从来没有好好学习关于Django中的Request和Response对象.借着文件上传下载的相关工作,现在总结一下也不错. 当一个页面请求过来,Django会自动创建一个Re ...

随机推荐

  1. 猫猫学iOS之UILabel设置圆角不成功所做调控更改

    原创文章.欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 如图问题 如图是我要做的效果 然而当我写好代码后,设置号label的layer圆角后 ...

  2. [RxJS] exhaustMap vs switchMap vs concatMap

    exhaustMap: It drop the outter observable, just return the inner observable, and it waits until prev ...

  3. CSDN挑战编程——《绝对值最小》

    绝对值最小 题目详情: 给你一个数组A[n],请你计算出ans=min(|A[i]+A[j]|)(0<=i,j<n). 比如:A={1, 4, -3}, 则: |A[0] + A[0]| ...

  4. 使用Win32 API实现生产者消费者线程同步

    使用win32 API创建线程,创建信号量用于线程的同步 创建信号量 语法例如以下 HANDLE semophore; semophore = CreateSemaphore(lpSemaphoreA ...

  5. Spring学习笔记——Spring事务仅仅对执行时异常回滚

    我们在使用Spring时候一般都知道事务在遇到异常的时候会回滚.岂不知Spring的事务默认仅仅有在发生执行时异常即:RunTimeException时才会发生事务,假设一个方法抛出Exception ...

  6. 【IOS 开发】Object - C 入门 之 数据类型具体解释

    作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/38544659 1. 数据类型简单介绍及输出 (1) 数据类型 ...

  7. Spring源代码解析和配置文件载入

    Spring类的继承结构图: Spring运用了大量的模板方法模式和策略模式,所以各位看源代码的时候,务必留意,每个继承的层次都有不同的作用.然后将同样的地方抽取出来,依赖抽象将不同的处理依照不同的策 ...

  8. WPF学习笔记——ListBox用ItemsSource绑定数据源

    作为一个WPF初学者,感到困难重重.在网上想查个ListBox绑定数据源的示例,结果出来一大堆代码,一看心就烦. 我给个简洁一点的代码: 后台代码: protected class UserItem ...

  9. luogu2161 [SHOI2009]会场预约

    题目大意 随着时间的推移这里有几个任务对应着一段区间.每次要将任务安到时间线上时,要把时间线上已有的与该任务对应区间有交集的区间对应的任务删去.求每次删去的区间个数,以及整个时间线上有几个任务.时间线 ...

  10. everything的使用

    https://www.voidtools.com/support/everything/searching/ 打开多个everything进程 https://www.voidtools.com/s ...