servlet学习笔记_4
一.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的更多相关文章
- # jsp及servlet学习笔记
目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...
- Servlet学习笔记(四)
目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...
- Servlet学习笔记(三)
目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...
- Servlet学习笔记(二)
目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...
- jsp&servlet学习笔记
1.路径引用问题 一个css.jsp.html.或者javascript文件从从一个工程复制到另一工程,如果引用的时候使用的时相对路径,看似没有错误,但是却一直引用不进来,这时候要使用绝对路径,这样才 ...
- Servlet 学习笔记
Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...
- Servlet学习笔记(1)--第一个servlet&&三种状态对象(cookie,session,application)&&Servlet的生命周期
servlet的404错误困扰了两天,各种方法都试过了,翻书逛论坛终于把问题解决了,写此博客来纪念自己的第一个servlet经历. 下面我会将自己的编写第一个servlet的详细过程提供给初学者,大神 ...
- Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain
笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤.最后response过滤,而且中间几项过滤的顺序不能动态改变.所 ...
- Servlet学习笔记(八)—— 文件下载
一.文件下载概述 比如图片或者HTML这类静态资源,仅仅要在浏览器中打开正确的网址就行下载.仅仅要资源放在应用程序文件夹或者其下的子文件夹中,但不在WEB-INF下.Servlet/JSP容器就会将资 ...
随机推荐
- 彻底卸载Oracle
彻底卸载Oracle 用Oracle自带的卸载程序不能从根本上卸载Oracle,从而为下次的安装留下隐患,那么怎么才能完全卸载Oracle呢?那就是直接注册表清除,步骤如下: 1. 开始->设置 ...
- MFC获取Windows启动状态(正常启动、安全模式启动、网络安全模式启动)
UINT nFlags = GetSystemMetrics(SM_CLEANBOOT); switch(nFlags) { : AfxMessageBox(TEXT("正常启动" ...
- OC的总结 ***希望对大家有帮助*** ---高小杰
1. NSLog 是Foundation提供的一个输出函数,它的功能非常强大,不仅可以输出字符串,还可以输出各种对象,到后面程序还会见到大量的使用NSLog()函数. 2. N ...
- 数据库备份checksum选项你会用么?
SQL SERVER有好多好多功能,选项也一大堆,很多功能选项并不常用.但是如果真有这种需求的时候又想不起来~ 本篇我们就来聊聊备份里的选项checksum,这是个啥玩意?听都没听过?来看下图: 就是 ...
- SQL 递归
-- 查询指定部门下面的所有部门, 并汇总各部门的下级部门数 ) SET @Dept_name = N'MIS' ;WITH DEPTS AS( -- 查询指定部门及其下的所有子部门 -- 定位点成员 ...
- c++调用lua注册的带参数的回调
main.cpp int lua_cb = LUA_REFNIL; int lua_cb_arg = LUA_REFNIL; int setcb(lua_State *L) { lua_pushval ...
- eclipse连hadoop2.x运行wordcount 转载
转载地址:http://my.oschina.net/cjun/blog/475576 一.新建java工程,并且导入hadoop相关jar包 此处可以直接创建mapreduce项目就可以,不用下面折 ...
- IOS修改webView背景透明以及IOS调用前台js的方法
工作上遇到IOS的webView中的H5页面需要透明以显示webView的背景颜色.用H5自身的透明度的css样式或者js控制背景颜色及透明度都打不到想要的效果,最后还是通过ios设置webView中 ...
- PostgreSQL的OGG -- bucardo
bucardo是PostgreSQL数据库中实现双向同步的软件,可以实现PostgreSQL数据库的双master的方案,不过bucardo中的同步都是异步的,它是通过触发器记录变化,程序是perl写 ...
- android应用刷新系统多媒体库(增加or删除多媒体文件)
系统:android4.4及其以上 功能:app中拍照, 并实现浏览.删除照片操作. 实现: 1.拍照,存储到指定路径path 2.通知系统多媒体数据库刷新数据. 主要使用MediaScannerCo ...