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.无论是请求转发还是请求重定向都不能有内容已经被实际输出到了客户端.

时间: 2024-12-06 23:04:29

servlet学习笔记_4的相关文章

测试servlet学习笔记

操作方法: 1.新建工程: File-->new-->Java Project-->TestServlet(工程名称)-->Finish. 2.加载servlet-api.jar类包: TestServlet(右键)-->Build Path-->Configure Build Path-->Library -->Add External JAR Selection-->(浏览在tomcat的lib目录下找到servlet-api.jar选中后点击打开

SERVLET 学习笔记

SERVLET 学习笔记 一.Servlet基本定义 Servlet是服务器端上面运行的一段小的java程序,一个servlet就是一个简答的java类.通常servlet都是通过请求和返回的模式来被访问的,客户端通过resuest请求,servlet则通过response来返回需要的内容. 二.Tomcat容器等级 Tomcat容器等级分为四个等级,由内向外分别是:context容器àSERVLET容器àHOST(主机)容器àENGINE(引擎)容器.其中,CONTEXT容器,一个CONTEX

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

笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,但是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤,最后response过滤,并且中间几项过滤的顺序不能动态改变.所以这里做个改进,实现一个过滤顺序的FilterChain. 多个Filter的执行顺序在这篇博文中得到很仔细的讲解,总结一点,多个过滤器的执行顺序是根据web.xml中不同<filter-mapping>的顺序来先后执行的,比如: <?xml version="1.0"

JavaWeb 后端 &lt;二&gt; 之 Servlet 学习笔记

JavaWeb 后端 <二> 之 Servlet 学习笔记 一.Servlet概述 1.什么是Servlet Servlet是一个运行在服务器端的Java小程序,通过HTTP协议用于接收来自客户端请求,并发出响应. 2.Servlet中的方法 public void service(ServletRequest req,ServletResponse res) throws ServletException,java.io.IOException ServletRequest req:代表着请

Servlet学习笔记(七)—— JSP概述

1.Servlet两个缺陷: ①所有HTML标签必须包在Java字符串中,使得发送HTTP响应十分繁琐: ②所有文本和HTML标签都必须进行硬编码,即使对表示层做极其微小的修改,也需要重新编译. 2.注释: (1)JSP备注:<% %>,不会发送到浏览器,不能嵌套 (2)HTML备注:<!-- -->,不被容器处理,直接发送到浏览器,用途之一是标识JSP页面.在处理带有许多JSP片段的应用程序时,开发者通过查看HTML源代码,可以轻松查出某个HTML代码部分生成了那个JSP页面.

Servlet学习笔记(六)—— 自定义过滤器的编写

Boss今天让我写一个类似BBS留言板的过滤器,要求对字符编码.登录权限.敏感词进行过滤操作. 总体分两模块: 一.过滤器 //Filter.java package lewa; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public interface Filter { public void init(); public void doFilter(ServletRequest reu

Other - 01 - Servlet学习笔记 - 概览

Servlet规范 本文第一段是 copy 过来的,请各位看官谅解,顺序结构参照 Servlet 3.1 规范. 什么是 Servlet Servlet 是基于 Java 技术的 web 组件,容器托管的,用于生成动态内容.像其他基于 Java 的组件技术一样,Servlet 也是基于平台无关的 Java 类格式,被编译为平台无关的字节码,可以被基于 Java 技术的 web server 动态加载并运行.容器,有时候也叫做 servlet 引擎,是 web server 为支持 servlet

Servlet学习笔记(九)—— 文件下载

一.文件下载概述 例如图片或者HTML这类静态资源,只要在浏览器中打开正确的网址就可以下载.只要资源放在应用程序目录或者其下的子目录中,但不在WEB-INF下,Servlet/JSP容器就会将资源发送到浏览器.但有的时候,静态资源被保存在应用程序目录之外,或者保存在数据库中,或者有时候你需要控制让某些人能够看到这个资源,同时又要防止其他网站引用它.每当遇到这类情况时,就必须通过编程来发送资源. 通过编程的方式实现文件下载可是让我们有选择的将一个文件发送到浏览器. 为了将资源比如文件发送到浏览器,

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

一.文件下载概述 比如图片或者HTML这类静态资源,仅仅要在浏览器中打开正确的网址就行下载.仅仅要资源放在应用程序文件夹或者其下的子文件夹中,但不在WEB-INF下.Servlet/JSP容器就会将资源发送到浏览器. 但有的时候,静态资源被保存在应用程序文件夹之外,或者保存在数据库中.或者有时候你须要控制让某些人可以看到这个资源,同一时候又要防止其它站点引用它.每当遇到这类情况时,就必须通过编程来发送资源. 通过编程的方式实现文件下载但是让我们有选择的将一个文件发送到浏览器. 为了将资源比方文件