Servlet 基础详解
来源:互联网 发布:孙可望 知乎 编辑:程序博客网 时间:2024/06/08 02:50
1. Servlet简介
Servlet是服务器端的重要组件,直译为服务端的小程序,它属于动态资源,用来处理请求,服务器接收到请求后会调用Servlet来处理请求。
Servlet的主要作用 :接收请求 ,处理请求 ,完成响应 。
例如:
当我们要完成一个登录功能时,用户会将输入的用户名和密码以POST请求的形式发送到服务器,但是服务器本身并不具有能力来读取用户发送的用户名和密码,也就不可能对用户名和密码进行验证,所以当服务器收到这类请求后需要将请求转个一个Servlet处理。
Servlet实现类由我们编写,而由Web服务器(Servlet容器)调用,每个Servlet都必须实现javax.servlet.Servlet
2.HelloServlet
(1) 创建一个类并实现Servlet接口
public class HelloServlet implements Servlet { @Override public void init(ServletConfig config) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } /** * service方法是Servlet最重要的方法,Servlet每次接收请求时 * 都会调用service方法 * request:代表的是请求报文,是浏览器发送给服务器的 * response:代表的是响应报文,是服务器发送给浏览器的 */ @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("这是我的第一个Servlet!!"); //向浏览器返回一个内容 //获取一个输出流 PrintWriter out = response.getWriter(); //通过流向浏览器输出一个内容 out.print(new Date()); } @Override public String getServletInfo() { return null; } @Override public void destroy() { }}
(2) 在WEB-INF目录下的web.xml文件中注册映射Servlet.
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.atguigu.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping></web-app><!-- 注册servlet servlet-name:Servlet的别名,在服务器中Servlet所有的配置都是通过别名,这个名字是给程序员用的,程序员通过别名对Servlet进行配置。 servlet-class:Servlet的全类名,用来创建Servlet实例, 这个名字是给服务器使用的,服务器通过全类名来创建Servlet实例。 url-pattern:为Servlet映射的请求地址,通过该地址可以访问我们创建的Servlet,这个名字是给用户使用的,用户通过该地址来访问Servlet。-->
3.Servlet的生命周期:Servlet对象从被创建到被销毁的过程。
当我们第一次访问Servlet时,有三个方法被调用了: 构造器 ,init ,service 。第一次以后每次访问,只会调用: service当服务器停止时: destroy
(1) 构造器 当Servlet第一次接收请求的时候调用,用来创建Servlet对象,只调用了一次。 Servlet是一个单例的,在服务器中同一个Servlet只有一个实例。 它是以多线程的形式调用service方法 Servlet不是线程安全,所以在service方法尽量不要操作全局变量(2) init() 在构造器调用之后马上被调用,用来初始化Servlet,只调用了一次。(3) service() 每次处理请求时,service都会调用,用来处理请求,会调用多次。(4) destroy() 当停止服务器时(项目卸载、Servlet对象销毁前),用来做一些收尾工作,只会调用一次。
4. ServletConfig
(1) 代表:SerlvetConfig代表的是Servlet的配置信息,具体来说就是Servlet标签中的内容,每一个Servlet都有其唯一的ServletConfig
(2) 获取:该对象由服务器创建,最终会作为参数传递到init()方法,我们可以在init中直接使用
(3) 功能
① 可以获取Servlet的别名
② 可以获取当前Servlet的初始化参数
③ 获取ServletContext对象:
@Override public void init(ServletConfig config) throws ServletException { //获取Servlet的别名 String servletName = config.getServletName(); System.out.println(servletName); //获取当前Servlet的初始化参数 String user = config.getInitParameter("user"); String pwd = config.getInitParameter("password"); System.out.println(user+"--"+pwd); //获取ServletContext对象 ServletContext servletContext = config.getServletContext(); System.out.println(servletContext); }
5.ServletContext
(1) 代表:ServletContext代表的是整个的WEB应用,每一个WEB应用都有其唯一的一个ServletContext
(2) 获取:通过ServletConfig的getServletContext()方法获取
(3) 功能:
① 获取整个WEB应用的初始化参数
② 获取资源的真实路径(主要用来做文件的上传和下载)
String realPath = servletContext.getRealPath("index.html");
真实路径(物理路径):C:\Users\lilichao\Desktop\day07\note\笔记.txt
虚拟路径:http://localhost:8080/08_WEB_Servlet/BServlet
③ 作为一个域对象在不同的WEB资源之间共享数据
@Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { //获取ServletContext ServletContext servletContext = config.getServletContext(); //获取整个web应用的初始化参数 String phone = servletContext.getInitParameter("phone"); System.out.println("phone = "+phone); //获取index.html的真实路径 String realPath = servletContext.getRealPath("hello.html"); System.out.println(realPath); }
6.GenericServlet
在显示开发中我们如果直接实现servlet接口功能也是可以正常实现的,但是所面临的问题是:如果我直接实现Servlet接口,那接口中的所有方法都必须要实现,但是这些方法有的我们用不到,而有的方法实现起来很麻烦而且没给servlet实现的代码都差不多,于是我们就需要一个抽象类来帮助我们实现servlet接口,实现一些通用的方法,而我们只需要继承GenericServlet就可以了,这样的好处是我们不在需要重写全部方法,而只需要重写必须的和我们需要的方法就可以。
7. HttpServlet
HttpServlet是GenericServlet的子类,他是Tomcat中专门处理HttpServlet的Servlet(实际上Tomcat只处理Http类型的请求)所以在一般情况下我们都会通过继承HttpServlet来实现servlet。
HttpServlet和GenericServlet一样都是一个抽象类,也就是不能对它们进行实例化,与GenericServlet不同HttpServlet中没有任何抽象方法,所以需要我们根据实际需求来重写它的方法。
在GenericServlet中service(ServletRequest req, ServletResponse res)方法是一个抽象方法,必须要由子类实现,而在HttpServlet中已经被实现,而在HttpServlet的实现的方法中会被强制转换成HttpServletRequest和HttpServletResponse(不用担心会出现类型转换异常,因为传过来的对象本身就是该类型)。转换类型之后会调用HttpServlet中的一个重载的service(HttpServletRequest req, HttpServletResponse resp)方法。也就是说如果我们要重写service()方法不必再去重写GenericServlet的service()方法了,而可以直接重写HttpServlet重载的service()方法就可以了。
在service(HttpServletRequest req, HttpServletResponse resp)方法中,会对它的请求类型进行判断,然后根据请求类型的不同再去调用不同的方法。如:post类型的请求回去调用doPost(),get请求回去调用doGet(),delete请求回去调用doDelete(),以此类推。但是在实际应用中我们只会使用到doPost()和doGet(),所以一般情况下我们不会去重写service()方法,而是去重写更简单的doGet()或者doPost()。
8.HttpServletRequest 和 HttpServletResponse
(1) HttpServletRequest
代表:代表的是浏览器发送给服务器的请求报文
获取:该对象由服务器创建最终作为参数传递doGet()或者doPost()方法中,我们可以在这两个方法中直接使用。
功能:
① 获取用户发送的请求参数
② 获取项目的名字(主要用来设置绝对路径)
③ 可以作为一个域对象在不同的web资源之间共享数据。
④ 可以做请求的转发:转发就是Servlet收到请求以后,自己不去处理请求,而是调用服务器内部的其他资源去处理请求
(2) HttpServletResponse
代表:代表是服务器发送给浏览器响应报文。
获取:该对象由服务器创建最终作为参数传递doGet()或者doPost()方法中,我们可以在这两个方法中直接使用。
功能:
① 向浏览器输出一个页面片段,这个方法实际上是在设置响应报文的响应体。
② 做请求的重定向
所谓的重定向,指Servlet收到浏览器发送的请求以后,返回给浏览器一个特殊的响应,这个特殊的响应告诉浏览器,再去向另一个地址发送请求。
③ 重定向的特点:
【1】重定向时浏览器发送了 2 次请求。
【2】重定向是在浏览器端发生。
【3】重定向时浏览器的地址栏会发生变化。
【4】浏览器可以知道重定向的发生。
(3) 代码说明
public class FServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * HttpServletRequest * 代表:代表的是浏览器发送给服务器的请求报文 * 获取:该对象由服务器创建最终作为参数传递doGet()或者doPost()方法中,我们可以在这两个方法中直接使用。 * 功能: * [1]获取用户发送的请求参数 * [2]获取项目的名字(主要用来设置绝对路径) * [3]可以作为一个域对象在不同的web资源之间共享数据。 * [4]可以做请求的转发 */ //获取用户发送的请求参数 String username = request.getParameter("um"); String password = request.getParameter("password"); //将用户名输出到页面中 response.getWriter().print("username = "+username +"<br />"); response.getWriter().print("password = "+password); //获取项目名 String contextPath = request.getContextPath(); System.out.println(contextPath); //发起请求的转发 //1.获取一个请求的派发器 RequestDispatcher dispatcher = request.getRequestDispatcher("target.html"); //2.使用派发器发起转发 dispatcher.forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * HttpServletResponse * 代表:代表是服务器发送给浏览器响应报文。 * 获取:该对象由服务器创建最终作为参数传递doGet()或者doPost()方法中,我们可以在这两个方法中直接使用。 * 功能: * [1]向浏览器输出一个页面或者是页面片段 * [2]做请求的重定向 */ //向浏览器输出一个页面片段 //这个方法实际上是在设置响应报文的响应体 //1.获取一个输出流 PrintWriter out = response.getWriter(); //2.通过这个流向浏览器输出一段信息 out.print("<h1>Hello Servlet!</h1>"); //做请求的重定向 response.sendRedirect("target.html"); }}
(4) 转发和重定向的对比:
在一般情况下,用户名验证码等都正确就重定向到成功页面,如果失败就转发到失败页面。例如:
重定向:response.sendRedirect(request.getContextPath()+ "/pages/user/regist_success.html" );
转 发 :request.getRequestDispatcher( "/pages/user/regist_error.html" ).forward(request,response);
9.字符编码
计算机在传输字符,需要将字符转换为二进制数据来传输,读取内容时又需要将二进制数据转换为字符,编码和解码所使用的规则,我们称为字符集,常见的字符集: ASCII、ISO-8859-1、GBK、GB2312、UTF-8。
产生乱码问题的根本原因:编码和解码所采用的字符集不同。
解决方案:统一编码和解码所采用的字符集为utf-8。
(1) 请求:浏览器 --> 服务器 :浏览器编码,服务器解码
① post请求
post请求是在Servlet中解码的,Servlet中默认使用iso-8859-1,而它不支持中文,所以肯定乱码,所以post请求我们只需要去指定request使用的字符集即可。
解决方案:在request.getParameter()方法第一次调用之前调用一下代码:request.setCharacterEncoding("utf-8");
② get请求
get请求是通过url地址来传递请求参数的,它会由Tomcat服务器自动解码,而服务器默认使用的是iso-8859-1。
解决方案:修改服务器默认的解码字符集,在server.xml配置文件中,在Connector标签中,添加一个 URIEncoding="utf-8"。最终为:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
(2) 响应:服务器 --> 浏览器 :服务器编码,浏览器解码。
解决方案:在向浏览器返回响应之前,调用如下代码:response.setContentType("text/html;charset=utf-8");
10.路径问题
URL地址的格式:http://主机地址:端口号/项目名/资源路径/资源名
(1) 相对路径:
相对路径相对于:http://主机地址:端口号/项目名/资源路径/
由于转发的出现,相对路径非常容易出错,所以在开发中我们不使用相对路径,而是使用绝对路径。
(2) 绝对路径
绝对路径使用 "/" 开头;
由浏览器去解析的绝对路径,这个"/"代表的是服务器的根目录,http://主机地址:端口号/
注意:由浏览器解析的绝对路径,我们需要添加上项目名。
由服务器解析的绝对路径,这个"/"代表的是项目的根目录
即:http://主机地址:端口号/项目名/所以由服务器解析路径不需要加上项目名。
(3) 常见的路径:
① url-pattern:
② 转发的路径:
url-pattern和转发的路径都是由服务器所解析的,是以项目的根目录为根目录,即: "/"代表的是项目的根目录:http://主机地址:端口号/项目名/
③ 重定向的路径:
④ 页面中的路径:
重定向和页面中的路径都是由浏览器解析的,是以服务器的根目录为根目录,即:"/"代表的是服务器的根目录:http://主机地址:端口号/
(5) base标签(HTML页面的处理方式):
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><!-- base标签中的href属性,将会作为页面中所有相对路径的前缀 --><!-- base标签的作用就是让我们可以以使用相对路径的方式使用绝对路径 --><!-- base标签只对相对路径起作用 --><base href="http://localhost:8080/10_WEB_Path/" /></head><body> <h1>我是网站的首页</h1> <!-- 使用绝对路径 --> <a href="/10_WEB_Path/hello/1.html">去1.html</a> <hr /> <!-- 使用base标签 --> <a href="hello/1.html">去1.html</a></body></html>
阅读全文
1 0
- Servlet类基础详解
- servlet基础详解
- Servlet 基础详解
- Servlet/JSP配置详解(基础篇)
- Servlet/JSP配置详解(非常基础)
- Servlet基础----Hello Servlet!!!
- Servlet基础
- Servlet基础
- Servlet基础
- servlet基础
- Servlet 基础
- Servlet基础
- servlet基础
- Servlet 基础
- Servlet基础
- Servlet基础
- servlet基础
- Servlet基础
- Java23种设计模式——访问者模式
- python大作战之递归和高阶函数
- Python 爬虫问题记录
- 搭建shadowsocks服务端
- 研究生互联网竞赛信息渠道
- Servlet 基础详解
- 《大话设计模式》之策略模式
- HDOJ1019 Least Common Multiple(求多个数的最小公倍数)
- 171121 逆向-静态分析安卓(特殊类)
- SpringMVC参数传递 使用model完成页面的回显
- 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
- haproxy透传用户ip-方法和原理
- Frontend Architecture for Design Systems.pdf 英文原版 免费下载
- 486. Predict the Winner