Servlet
一.实现Servlet
1、新建普通class类
2、继承HttpServlet类
3、重写service()方法
4、配置web.xml
二. 工作原理
三. Servlet 的生命周期
Servlet 没有 main()方法,不能独立运行,它的运行完全由 Servlet 引擎来控 制和调度。 所谓生命周期,指的是 servlet 容器何时创建 servlet 实例、何时调 用其方法进行请求的处理、 何时并销毁其实例的整个过程。(此处讨论默认的生 命周期)
实例和初始化时机
当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会 创建实例并 进行初始化。
就绪/调用/服务阶段
有请求到达容器,容器调用 servlet 对象的 service()方法,处理请求的方法在 整个声明周 期中可以被多次调用;
HttpServlet 的 service()方法,会依据请求方式来调用 doGet()或者 doPost() 方法。但是, 这两个 do 方法默认情况下,会抛出异常,需要子类去 override。
销毁时机
当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。
上述的生命周期可以通过 Servlet 中的生命周期方法来观察。在 Servlet 中 有三个生命周 期方法,不由用户手动调用,而是在特定的时机有容器自动调用, 观察这三个生命周期方法 即可观察到 Servlet 的生命周期。
四.请求乱码解决
request 属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为 ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。
要想解决这种乱码问题,需要设置 request 中的编码方式,告诉服务器以何种方式来解析数据。或者在接收到乱码数据以后,再通过相应的编码格式还原。
POST请求:Tomcat8及以上和Tomcat7及以下版本都会乱码
GET请求:Tomcat8及以上不会乱码,Tomcat7及以下会乱码
方案一:
设置请求的编码 (只针对于POST请求有效,必须在接收所有的数据之前设定)
request.setCharacterEncoding("UTF-8");
方案二:
new String(request.getParameter("参数名").getBytes("ISO-8859-1"),"UTF-8");
无论是GET请求还是POST请求都适用。一次只能处理一个参数
五.请求转发
请求转发,是一种服务器的行为.
当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变
得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。
实现方式如下,达到多个资源协同响应的效果
request.getRequestDispatcher("请求的地址").forward(request,response);
六.request作为域对象
通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。
request.setAttribute():设置域对象内容;
request.getAttribute(String name):获取域对象内容;
request.removeAttribute(String name): 删除域对象内容。
request 域对象中的数据在一次请求中有效,则经过请求转发,request 域中的数据依然 存在,则在请求转发的过程中可以通过 request 来传输/共享数据。
七.响应数据
接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流,
有两种形式 :
getWriter()获取字符流(只能响应回字符);
getOutputStream()获取字节流(能响应一切数据)。
响应回的数据到客户端被浏览器解析。
注意:两者不能同时使用。
八.乱码解决
如果响应的内容中含有中文,则有可能出现乱码。
这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
getWriter()的字符乱码
对于 getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
所以要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式,
比如我们通常用的“UTF-8” resp.setCharacterEncoding("UTF-8");,
此时还只完成了一半的工作,要保证数据正确显示,还需要指定客户端的解码方式
resp.setHeader("content-type", "text/html;charset=UTF-8");,
和服务器一致。两端指定编码后,乱码就解决了。
一句话:保证发送端和接收端的编码一致
getOutputStream()字节乱码
对于 getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示,这就看人品了^_^。
当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。
无论如何我们都应该准确掌握服务器和客户端使用的是那种编码格式,以确保数据正确显示。指定客户端和服务器使用的编码方式一致即可 。
总结:
乱码的原因:
1、客户端和服务端编码不一致
2、编码不支持中文
解决方案:
保证客户端和服务端编码一致且支持中文
response.setContentType("text/html;charset=UTF-8");
九.请求转发和重定向
1、只有一次请求,request作用域中的数据可以共享
2、浏览器地址栏不发生改变
3、服务端行为
4、跳转的绝对地址可以定位到站点名后
只能请求转发到当前项目下的资源
重定向的区别
1、有两次请求,request作用域中的数据不可以共享
2、浏览器地址栏发生改变
3、客户端行为
4、跳转的绝对地址可以定位到http://后面
重定向可以定位到任意资源
请求转发和重定向不能同时使用
路径问题
相对路径
路径的前面不要加任何符号,一般情况下代表的是: "http://localhost:8080/站点名/"
绝对路径
1、以http://开头的,完整的绝对路径,可以跨域,可以访问任何资源
2、以"/"开头,只能访问当前项目下的资源
请求转发和重定向的"/"代表的含义:
1、请求转发(服务端跳转):"http://localhost:8080/站点名/"
2、重定向(客户端跳转):"http://localhost:8080/"
客户端跳转:
表单提交、超链接跳转、地址栏直接收入、重定向
服务端跳转:
请求转发
HttpServletRequest的常用方法:
setCharacterEncoding(“编码方式”);
设置请求内容的编码方式(这句话必须在获取任何请求参数值之前)
String getParameter(“参数名”);
用来获取请求参数(表单,URL重写)的值(参数名通常是表单元素的name属性值)
HttpServletResponse的常用方法:
setCharacterEncoding(“编码方式”);
设置响应内容的编码方式得到向客户端浏览器输出HTML内容的字符流对象
PrintWriter getWriter();
得到向客户端浏览器输出HTML内容的字符流对象
sendRedirect(“URL地址”);
客户端浏览器重定向(命令客户端跳转)也简称为:客户端跳转,外部(在服务器之外)跳转。
十、重定向
1)什么是重定向?
服务器向浏览器发送一个状态码302及一个location消息头(值是一个地址,称之为重定向地址),
浏览器收到后,会立即向 location所指向的地址发送请求。
2)如何重定向
response.sendRedirect(String url); 其中,url是重定向的地址。
3)编程要注意的问题
a、重定向之前,不能够有out.close()或者out.flush()操作。(否则会报错)
有out.close或者out.flus时,请求经处理后要把处理结果打包响应给浏览器。
而response.sendRect也是对浏览器请求的响应,这样就造成了一次请求两次响应,不符合规范.
b、重定向之前,如果response对象缓存有数据,则这些数据会被清空。
重定向后,只发送一个重定向地址,不会发送实体内容。所以response对象会清空。
response对象里装的是返回给浏览器的实体内容。
4)重定向的特点
重定向的地址是任意的
重定向之后,浏览器地址栏的地址变成了location所指定的地址