request_response

 每次请求service()方法,都会由容器创建一个新的对象

 

Request和response在每一次访问时都被创建。由容器创建的

Serlvet只会被创建一次,由用户来开发,由容器来创建,单一的实例。

ServletConfig会为每一个Servlet创建一个Config对象,且由Servlet维护。就是声明成了成员变量。

ServletContext对象,是这一个项目就只有一个此对象。

 

Servlet API 中定义的 ServletRequest 接口类用于封装请求消息。

HttpServletRequest 是专用于HTTP协议的ServletRequest 子接口,它用于封装 HTTP 请求消息。

在 service() 方法内部调用 HttpServletRequest 对象的各种方法来获取请求消息。

 

Request功能:

接收用户的参数、接收用户的所有请求头信息、转发、包含、做为域对象也可以存放数据

1.HttpServletRequest是ServletRequest的子接口,它获取http请求

(1)获取请求参数:

getParameter("name"):根据请求参数名获取参数值,

getParameterValues (String)方法:根据请求参数名获取一组值

getParameterNames ()方法 :获取所有参数的名字

getParameterMap ()方法 获取所有数据,,返回类型为Map

// 获取名字<input type="text" name="name">的值
String name = req.getParameter("name");
// 爱好<input type="checkbox" name="hobby" value="read">
String[] hobbys = req.getParameterValues("hobby");
// 性别<input type="radio" name="sex" value="male">
String sex = req.getParameter("sex");
// 显示到页面上
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("你叫:" + name + "<br/>");
out.print("你的爱好是:<br/>");
for (String h : hobbys) {
  out.print(h + "<br/>");
}
out.print("你的性别是:" + sex + "<hr/>");
// 使用getParameterNames()获取所有参数名字
Enumeration<String> names = req.getParameterNames();
while (names.hasMoreElements()) {
String nm = (String) names.nextElement();
  out.print("获取到的名字:" + nm + "<br/>");
}
out.print("<hr/>");

// 使用getParameterMap()获取所有数据
Map<String, String[]> map = req.getParameterMap();
for (Entry<String, String[]> en : map.entrySet()) {
  out.print(en.getKey() + "<br>");
  String[] vs = en.getValue();
  for (String str : vs) {
    out.print(str + "<br>");
  }
  out.print("<hr/>");
}

获取参数时的乱码问题

解决办法

 

 1     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2                 
 3         //第一种方式  对get和post请求都有效
 4         //可以向name值转成最原始的字节码
 5         String name0 = request.getParameter("username");//现在这是name的编码格式iso-8859-1
 6         System.out.println(name0);
 7         byte[] byte1 = name0.getBytes("iso-8859-1");//根据iso-8859-1获取字节码
 8         //把字节码转成utf-8类型的字符串
 9         String name1=new String(byte1,"utf-8");
10         System.out.println("name1:"+name1);
11         
12         //第二种方式  只对post请求有效        
13         request.setCharacterEncoding("utf-8");
14         String name = request.getParameter("username");//现在这是name的编码格式iso-8859-1
15         System.out.println(name);        
16     }
1     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2         
3         //如果tomcat7以及以前的需要进行编码,可以在server.xml中的<Connector>节点中加入URIEncoding="utf-8",
4         //需要在eclipse和本地中的server.xml中的<Connector>节点中加入URIEncoding="utf-8"        
5         //tomcat8以及以上不需要加入该配置
6         String name = request.getParameter("username");//现在这是name的编码格式iso-8859-1
7         System.out.println(name);
8     }

获取请求的相关信息

 

 1 @Override
 2 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 3   resp.setContentType("text/html;charset=uTF-8");
 4   PrintWriter out = resp.getWriter();
 5   out.print("请求类型:"+req.getMethod()+"<br/>");
 6   out.print("请求协议:"+req.getProtocol()+"<br/>");
 7   out.print("请求地址:"+req.getRequestURI()+"<br/>");
 8   out.print("你的ip:"+req.getRemoteAddr()+"<br/>");
 9   out.print("请求:"+req.getQueryString()+"<br/>");
10   out.print("请求主机:"+req.getHeader("Host")+"<br/>");
11   out.print("http字符获取:"+req.getScheme()+"<br/>");
12   out.print("获取根目录:"+req.getContextPath()+"<br/>");     
13   out.print("请求来自哪里:"+req.getHeader("Referer")+"<hr/>");
14   //以下获取所有头信息
15   Enumeration<String> en = req.getHeaderNames();
16   while(en.hasMoreElements()){
17     String key = en.nextElement();
18     out.print(key+"=="+req.getHeader(key)+"<br/>");
19   }
20 }

防止盗链接 

 1 @Override
 2 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 3   String refer = req.getHeader("Referer");
 4   resp.setContentType("text/html;charset=utf-8");
 5   if(refer==null){
 6     resp.getWriter().print("请先去首页,<a href='index.jsp'>这是链接</a>");
 7   }else{
 8     resp.getWriter().print("图片:<img src='imgs/a.jpg'/>");
 9   }
10 }

Content-Type 媒体信息类型

Returns the MIME type of the body of the request, or null if the type is not known.

获取方式: request.getContextType()

  • 如果是get的请求,则此值为null
  • 如果是post普通的表单请求,则请求的类型可以是 application/x-www-form-urlencoded
  • 如果是需要上传文件,则此类型为 multipart/form-data

转发:是将请求在服务器内部交给另一个组件再去执行,同时共享request中的数据

 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        System.out.println("forwardServlet....");
        request.setAttribute("name", "zhangsan");
        System.out.println(request.getAttribute("name"));
        //请求转发:把请求转发给testServlet进行处理
        String path="testServlet";
        
        //通过request.getRequestDispatcher(path).forward(request, response);完成请求转发
        //getRequestDispatcher(path)需要传入请求转发的地址
        request.getRequestDispatcher(path).forward(request, response);
    }

 

 

 

请求域属性

存储在ServletRequest对象中的属性称之为请求域属性,属于同一个请求的多个处理模块之间可以通过请求域属性来传递对象数据。

与请求域属性相关的方法:

setAttribute方法、getAttribute方法 、removeAttribute方法、getAttributeNames方法

2.HttpServletResponse是ServletResponse子接口,封装了响应信息,针对于Http协议定制
常用方法:
setContentType("text/html;charset=utf-8"):设置响应内容类型
getWriter():返回PrintWriter对象,可以调用这个对象的writer()或print()方法,把响应内容输出到浏览器上

Servlet API中定义的ServletResponse接口类用于创建响应消息。

HttpServletResponse是专用于HTTP协议的ServletResponse子接口,它用于封装HTTP响应消息。

Response功能

  • 设置响应内容

         给用户输出html数据

  • 设置响应头

         请求的时的请求头由tomcat服务器来读取,但响应时的响应头由浏览器来读取,用于影响浏览器的行为。如是否要缓存这次响应的数据、状态码

  • 重定向

         就是将请求发送回浏览器。然后由浏览器再重新向服务器自动的发送一个请求。

 

设置响应内容 字符流输出

  • 方法:resp.getWiter() :  PrintWriter
  • 如果仅是输出 html信息,文本信息,则就可以使用字符。

重定向

请求重定向:指的是一个web资源受到客户端请求后,通知客户端去访问另外一个web资源

sendRedirect

使用方法:response.sendRedirect(路径)

 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("redirectServlet.....");
        request.setAttribute("name", "zhangsan");
        System.out.println(request.getAttribute("name"));
        //重定向
        response.sendRedirect("testServlet");
    }

 

 

 

 特点

  • 浏览器会向服务器发送两次请求,意味着会有两个request/respose
  • 浏览器地址栏会发生变化。
  • 不会共享request中的数据。
  • 执行重定向状态码为302.
  • 重定向的URL可以是其他应用,不局限于当前应用,例如重定向到百度

重定向和转发的比较

  • 转发只能将请求转发给同一个WEB应用中的组件;

  重定向可以到同一个站点上的其他应用程序中的资源,也使用绝对URL重定向到其他站点的资源。

  • 转发时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录;

  重定向相对URL以“/”开头,它是相对于整个WEB站点的根目录。

  • 转发是由服务器内部实现的。

  重定向由浏览器再次发出一个请求。

  • 转发方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程,共享数据;

  重定向方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程,所以数据不共享。

  • 转发后浏览器地址栏保持初始的URL地址不变。

  重定向后浏览器地址栏保持初始的URL地址改变。

  • 转发时请求的类型不变

  重定向时 的被调用者的请求类型只能是get

重点:
请求转发和请求重定向区别:
本质的区别:请求转发发了1次请求,重定向发了两次请求
1).请求转发:地址栏还是请求的地址栏
重定向:地址栏不再是第一次请求的地址,而是最后一次请求的地址

2).请求转发:在最终的servlet中,request对象和中转的request对象是同一个对象
重定向:在最终的servlet中,request对象和中转的request对象不是同一个对象

3)请求转发:/代表的是当前web应用的根目录 http://localhost:8080/demo2--》这就是web应用的根目录
重定向:/代表当前web站点的根目录 http://localhost:8080--》这就是一个站点

4)请求转发:只能转发到当前web应用
重定向:可以重定向到外部资源

 

posted @ 2019-02-21 21:22  尝胆  阅读(397)  评论(0编辑  收藏  举报