一.response.
1.response.characterEncoding和response.setContentType("text/html;charset=UTF-8"),response.setCharacterEncoding是设置服务器端输出的编码,而response.setContentType(),既指定了 服务器端的编码,又指定了浏览器端的编码.
2.常见的方法:

response.setStatus(int)://设置状态码,通常需要和响应头一起结合.例如302状态码和location一起结合等
response.setHeader/response.addHeader://当添加的两个响应头的键相同时,前者会覆盖,后者保留两个响应头.
response.setHeader("Refresh","2;URL=http://www.baidu.com");//设置响应头,2s后转向指定的URL
response.setHeader("Refresh","2");//每隔两秒刷新一次..
//下面的三个方法设置禁止浏览器使用缓存
response.setDateHeader("Expires",0);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");

3.在浏览器中模拟响应头(meta标签)
<meta http-equiv="Expires" content="0">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
注意web服务器发送的响应头字段的优先级比meta标签要高
4.response.getWriter方法和getOutPutStream方法:
1.两个方法不能同时使用.
2.response.getWriter方法返回的是PrintWriter对象,而response.getOutPutStream方法返回的是ServletOutPutStream对象.
3.可以用getOutPutStream方法输出字符,但是要先转化为字节数组,比较麻烦.
几个小细节:
1.response.getWriter()在一个service方法中进行多次调用,返回的是同一个对象,而response.getOutPutStream也一样.
2.response.getWriter()返回的PrintWriter的print方法和write方法几乎一样,print方法的底层实际上调用的就是write方法,唯一的区别就是如果要写入的字符为null,write会报异常,而print方法会写出null这个字符串

二.Request
1.如果在请求体中和get请求中包含同样的键,那么get请求中的值将会把请求体的值(post请求)给覆盖.
2.request.getParameter()方法一些需要注意的地方:
1.如果传递的参数不存在对应的键值对,返回null
2.如果传递的参数存在对应的键,但是键里没有赋值,那么返回空字符串
3.如果传递的参数存在对应的键,但是该键对应多个值,那么返回第一个匹配的字符串.想要将一个键对应的两个值都获取到用request.getParameterValues(name)
3.request.getRequestURI和request.getContextPath:
有一个URL:http://localhost:8080/day15_request1/DemoServlet1?username=14
request.getRequestURI:获取请求行中的资源部分,即位于URL的主机和端口之后,参数之前的部分.对上面的例子:/day15_request1/DemoServlet1
Request.getContextPath:获取用于获取请求请求URL中属于web应用程序的路径./day15_request1

4.request.getHeader(String name):获取指定名称的请求头,如果有多个获取第一个

request.getHeaderNames():获取所有请求头的键的枚举

 request.getHeaders(String name):获取指定名称的所有的请求头,返回的是枚举,记录了一个键所对应的多个值

三.请求包含和请求转发

1.请求包含

有以下几个细节需要注意:
1>.服务器不会去调整HttpServletRequest对象,因此HttpServletRequest对象依然保持的是初始的参数路径和信息.被包含者调用程序检测当前访问路径的时候,依然得到的是调用者的路径.
2>.被包含的如果是servlet程序,不能改变相应的状态码和状态头,如果它里面存在这样的语句,语句的执行结果将被忽略
3>.可以通过request.getQueryString获得整个查询参数,但是需要注意的是,如果在浏览器请求某个servlet的时候,没有携带参数,就算包含的时候携带了参数,这个方法也会返回null.但是如果在请求转发的getRequestDispatcher方法的括号内有参数,依然可以通过request.getParameter方法获取
4>.如果包含的是静态页面,Tomcat的缺省servlet会检查当前HttpServletResponse对象是否已经调用getWriter方法返回对象,如果已经调用就使用PrintWriter的write方法写出静态html的内容,如果没有调用,则会调用getOutPutStream方法的write方法直接写出到缓冲区中.因此就会存在一个问题:下面的代码会报错:

getServletContext().getRequestDispatcher("/a.html").forward(request,response);
response.getWriter().write("你在干嘛");

这是因为在缺省servlet中已经调用了getOutputStream了,而在这里又调用了getWriter方法,两个方法是冲突的.
此外输出html文件的时候可能会有意想不到的乱码问题.如果在请求转发到静态页面之前调用了getWriter方法,且没有指定content-type,那么就会用ISO8859-1对静态页面进行编码输出(这样子可能会乱码),否则直接将静态页面用流输出.
5>.RequestDispatcher接口封装了某个路径所指定的资源对象.注意:WEB-INF目录对RequestDispatcher接口是可见的.
6>.对于request.getRequestDispatcher()方法,如果请求转发的是html就读取文档发送到客户端,而如果请求转发的是jsp,就读取相应结果发送到客户端.因此,相当于缓冲区已经清空,结果已经提交给客户端,所以之后不能再调用include或者sendRedirect方法,这样会报错.
7>.RequestDispatcher对象只能包装当前web应用程序中的资源,所以forward和include方法只能实现一个web应用程序之间的转发请求和资源包含.
8>.在包含的时候,如果同时调用response.getWriter方法,实际上返回的对象是一样的,可以通过直接打印观察出来.
9>.请求包含jsp文件存在的问题:
1>>.乱码.如果不在请求的servlet处设置编码,那么jsp一定会发生乱码,因为jsp是动态资源,而且jsp中页面的内容是用response.getWriter写出的.因此为了防止jsp文件乱码,必须要在包含的servlet处设置编码!!!而html文件则不存在这种问题,因为DefaultServlet会直接将test.html文件按字节流原封不动的读取出来,再按字节流原封不动的写出.在客户端,会直接根据<meta>标签进行解析.
2>>.冲突.上面说过了JSP文件是调用response.getWriter()方法输出页面的,因此如果在包含的servlet处调用了response.getOutputStream方法,就会报错.

3>>jsp与普通静态页面的区别在于普通静态页面在请求的servlet处可以调用getOutPutStream方法,它会直接用字节流的形式进行输出(此时页面不能有getWriter方法)但是jsp只以getWriter形式输出,因此在转发jsp的时候,转发页面一定不能用getOutputStream方法.

2.请求转发.

1>.调用requestDispatcher().forward方法时,servlet容器将根据目标资源路径对当前HttpServletRequest对象中的请求路径和请求参数进行调整.例如下面的示例:

@WebServlet(name = "ForwardTestServlet", urlPatterns = "/ForwardTestServlet")
public class ForwardTestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma","no-cache");
response.setContentType("text/html;charset=UTF-8");
request.getRequestDispatcher("/ForwardTestServlet2?name=hlhdidi").forward(request, response);
}
@WebServlet(name = "ForwardTestServlet2", urlPatterns = "/ForwardTestServlet2")
public class ForwardTestServlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uri=request.getRequestURI();
StringBuffer url=request.getRequestURL();
String query=request.getQueryString();
response.getWriter().write("uri="+uri+"<br>");
response.getWriter().write("url="+url+"<br>");
response.getWriter().write("query="+query);
}

输出结果:

如果是请求包含,将ForwardTestServlet中的forward改为Include,结果如下:

可以看出于请求包含对请求头不做出修改不同,请求转发对请求行做出了修改,也可以获取查询的参数了.
2.forward一个静态资源时候的过程:
如果在访问一个静态资源转发前,调用了getWriter方法,那么直接用getWriter的write方法写出这个静态资源,步骤是先将资源中的内容转化为字符文本后再输出.
如果没有调用,直接将静态资源的流传出去.(涉及getOutputStream方法)

3.在调用forward方法之前写入缓冲区的数据将会在调用forward方法的时候被清空,而在调用完forward方法之后写入的数据,将被忽略.这里注意,缓冲区清空这种情况只出现在请求转发中,而请求包含,在调用Include方法前和方法后都可以继续写数据且在页面正常相应.
4.在调用者程序中设置的响应状态码和响应头都不会忽略,而在被调用者程序中设置的响应状态码和响应头也不会忽略(和请求包含不同).被调用者相同的数据会把调用者的数据覆盖.

四.请求重定向和请求转发的比较

1.请求转发只能将请求转发给同一个web应用的组件而请求重定向可以转发到同一个站点上的其他web应用资源

2.请求重定向会改变浏览器显示的URL,而请求转发不会

3.请求转发调用者和被调用者共享同一个request和response,而请求重定向调用者和被调用者分别有自己的request和response.

4.无论是请求转发还是请求重定向都不能有内容已经被实际输出到了客户端.

servlet学习笔记_4的更多相关文章

  1. # jsp及servlet学习笔记

    目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...

  2. Servlet学习笔记(四)

    目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...

  3. Servlet学习笔记(三)

    目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...

  4. Servlet学习笔记(二)

    目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...

  5. jsp&servlet学习笔记

    1.路径引用问题 一个css.jsp.html.或者javascript文件从从一个工程复制到另一工程,如果引用的时候使用的时相对路径,看似没有错误,但是却一直引用不进来,这时候要使用绝对路径,这样才 ...

  6. Servlet 学习笔记

    Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...

  7. Servlet学习笔记(1)--第一个servlet&&三种状态对象(cookie,session,application)&&Servlet的生命周期

    servlet的404错误困扰了两天,各种方法都试过了,翻书逛论坛终于把问题解决了,写此博客来纪念自己的第一个servlet经历. 下面我会将自己的编写第一个servlet的详细过程提供给初学者,大神 ...

  8. Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain

    笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤.最后response过滤,而且中间几项过滤的顺序不能动态改变.所 ...

  9. Servlet学习笔记(八)—— 文件下载

    一.文件下载概述 比如图片或者HTML这类静态资源,仅仅要在浏览器中打开正确的网址就行下载.仅仅要资源放在应用程序文件夹或者其下的子文件夹中,但不在WEB-INF下.Servlet/JSP容器就会将资 ...

随机推荐

  1. javascript中通过匿名函数进行事件绑定

  2. mysql 卸载 linux

    root@localhost ~]# rpm -qa | grep -i mysqlMySQL-client-5.5.52-1.linux2.6.x86_64MySQL-server-5.5.52-1 ...

  3. Wireshark工控协议

    Wireshark是一个强大开源流量与协议分析工具,除了传统网络协议解码外,还支持众多主流和标准工控协议的分析与解码. 序号 协议类型 源码下载 简介 1 Siemens S7 https://git ...

  4. 缓存Cache

    转载自  博客futan 这篇文章将全面介绍有关 缓存 ( 互动百科 | 维基百科 )cache以及利用PHP写缓存caching的技术. 什么是缓存Cache? 为什么人们要使用它? 缓存 Cach ...

  5. java第二次作业

    这次通过学习,我掌握了下拉菜单和单选按钮的使用下拉菜单构造方法:JComboBox() 创建具有默认数据模型的 JComboBox.JComboBox(ComboBoxModel aModel) 创建 ...

  6. 设置Beyond Compare 为 Git 默认的比较工具

    对于Beyond Compare4,Git版本号在2.2.0之后的,请在Git中依次输入以下命令: git config --global diff.tool bc3 git config --glo ...

  7. Rest Post示例(java服务端、python客户端)

    前提:服务端是现成的,java.springMVC.resttemplate.jboss等:突然有个需要,要在windows上开发一个客户端,作用是定期向服务端上传文件.想了想,如果客户端写一个jav ...

  8. windows+caffe(六)——convert.bat

    convert.bat的格式为 convert_imageset.exe的位置+空格+FLAGS+空格+图片所在的位置+空格+你生成的list的位置+空格+将要生成的db格式要保存的位置 建议都使用绝 ...

  9. 关于yuv格式

    首先,内存分布        1:YUV420          (1):I420:              YYYYYYYY UU VV    =>YUV420P          (2): ...

  10. 【转】Android选项卡置底的方法

    转载地址:http://www.oschina.net/code/snippet_163910_6092 发现很多Android应用的选项卡 都是显示在页面底部的,网上有资料:通过反射获取TabWid ...