Servlet(Server Applet),全称Java Servlet,暂无中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
一、手动配置servlet
1、自定义类实现servlet接口,重写相对应的方法
2、在Web.xml进行配置和映射servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Web_14</display-name>
<!-- 配置servlet -->
<servlet>
<servlet-name>login.servlet</servlet-name>
<servlet-class>com.sun.servlet.InitServlet</servlet-class>
<init-param>
<param-name>admin</param-name>
<param-value>123</param-value>
</init-param>
<init-param>
<param-name>sa</param-name>
<param-value>456</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- 映射 -->
<servlet-mapping>
<servlet-name>login.servlet</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
二、servlet容器
1,Tomcat是Servlet的运行环境,即一个Servlet容器。
2,Servlet容器的作用是负责处理客户请求,当客户请求来到时,Servlet容器获取请求,然后调用某个Servlet,并把Servlet的执行结果返回给客户。
3,Servlet容器的工作过程是:当客户请求某个资源时,Servlet容器使用ServletRequest对象把客户的请求信息封装起来,然后调用java Servlet API中定义的Servlet的一些生命周期方法,完成Servlet的执行,接着把Servlet执行的要返回给客户的结果封装到 ServletResponse对象中,最后Servlet容器把客户的请求发送给客户,完成为客户的一次服务过程。每一个Servlet的类都执行 init()、service()、destory()三个函数的自动调用,在启动时调用一次init()函数用以进行参数的初始化,在服务期间每当接收到对该Servlet的请求时都会调用Service()函数执行该Servlet的服务操作,当容器销毁时调用一次destory()函数。
4,典型的Servlet应用是监听器、过滤器的实现。
三、servlet生命周期(由servlet容器调用)
①构造器:第一次请求servlet时,创建servlet实例,调用构造器,只能被调用一次(单实例)
②init方法:只能被调用一次,在创建好实例后立即被调用,用于初始化当前的servlet
③service:每次请求都会调用service,被多次调用,用于做数据交互
④destroy:只能调用一次,服务器关闭时调用
四、load-on-startup(指定servlet被创建的时机)
1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
2)它的值必须是一个整数,表示servlet应该被载入的顺序
2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
5)当值相同时,容器就会自己选择顺序来加载。
五、servlet-mapping的URL通配符
1、 *.扩展名
2、 /*
注意:两者只能选择其一使用,不能同时用
<servlet-mapping>含有<servlet-name>和<url-pattern>
- <servlet-name>:Servlet的名字,唯一性和一致性,与<servlet>元素中声明的名字一致。
- <url-pattern>:指定相对于Servlet的URL的路径。该路径相对于web应用程序上下文的根路径。<servlet-mapping>将URL模式映射到某个Servlet,即该Servlet处理的URL。
六、servletConfig
1、配置servlet的初始化参数(配置<servlet>标签中)
2、获取参数的值和名字
//已知名字获取值
/*String s1=config.getInitParameter("admin");
String s2=config.getInitParameter("sa");
System.out.println(s1+" "+s2);*/
//未知名字和值获取初始化的名字和值
Enumeration<String> strs=config.getInitParameterNames();
while(strs.hasMoreElements()){
String name=strs.nextElement();
System.out.println(name+"的值为:"+config.getInitParameter(name));
七、servlet体系结构
①servlet接口
在Servlet接口中定义了5个方法,其中3个方法都是由Servlet容器来调用的,容器会在Servlet的生命周期的不同阶段调用特定的方法:
- init(ServletConfig) —— 负责初始化Servlet对象,容器在创建好Servlet对象后,就会调用该方法;
- service(ServletRquest req, ServletResponse res) —— 负责相应客户的请求,为客户提供相应服务。当容器接受到客户端要求访问特定Servlet对象的请求时,就会调用该Servlet对象的service()方法;
- destroy() —— 负责释放Servlet对象占用的资源。当Servlet对象结束声明周期时,容器会调用此方法;
②GenericServlet
GenericServlet抽象类为Servlet接口提供了通用实现,它与任何网络应用层协议无关。
GenericServlet除了实现了Servlet接口,还实现了ServletConfig接口和Serializable接口:
GenericServlet类实现了Servlet接口中的init(ServletConfig config)初始化方法。GenericServlet类有一个ServletConfig类型的private成员变量,当Servlet容器调用GenericServlet的init(ServletConfig)方法时,该方法使得私有变量引用由容器传入的ServletConfig对象。GenericServlet类还定义了一个不带参数的init()方法,init(ServletConfig)方法会调用此方法。因此在子类中重写init时,最好重写init()方法,若重写Init(ServletConfig)方法,还需要先调用父类的init(ServletConfig)方法(super.init(config))。
GenericServlet类没有实现Servlet接口中的service()方法。service()方法是GenericServlet类中唯一的抽象方法,GenericServlet类的具体子类必须实现该方法。
GenericServlet类实现了Servlet接口的destroy()方法,但实际什么也没做。
GenericServlet类实现了ServletConfig接口的所有方法。
③HttpServlet
HttpServlet类是GenericServlet类的子类。HttpServlet类为Serlvet接口提供了与HTTP协议相关的通用实现,也就是说,HttpServlet对象适合运行在与客户端采用HTTP协议通信的Servlet容器或者Web容器中。
HttpServlet类实现了Servlet接口中的service(ServletRequest , ServletResponse)方法,而该方法实际调用的是它的重载方法HttpServlet.service(HttpServletRequest, HttpServletResponse);
在上面的重载service()方法中,首先调用HttpServletRequest类型的参数的getMethod()方法,获得客户端的请求方法,然后根据该请求方式来调用匹配的服务方法;如果为GET方式,则调用doGet()方法,如果为POST方式,则调用doPost()方法。
HttpServlet类为所有的请求方式,提供了默认的实现doGet(),doPost(),doPut(),doDelete()方法;这些方法的默认实现都会向客户端返回一个错误。
对于HttpServlet类的具体子类,一般会针对客户端的特定请求方法,覆盖HttpServlet类中的相应的doXXX方法。如果客户端按照GET或POST方式请求访问HttpsServlet,并且这两种方法下,HttpServlet提供相同的服务,那么可以只实现doGet()方法,并且让doPost()方法调用doGet()方法。
八、隐式(内置)对象与servlet对应的关系
隐式对象 | 说明 |
out | 转译后对应JspWriter对象,其内部关联一个PringWriter对象 |
request | 转译后对应HttpServletRequest/ServletRequest对象 |
response | 转译后对应HttpServletRespons/ServletResponse对象 |
config | 转译后对应ServletConfig对象 |
application | 转译后对应ServletContext对象 |
session | 转译后对应HttpSession对象 |
pageContext | 转译后对应PageContext对象,它提供了JSP页面资源的封装,并可设置页面范围属性 |
exception | 转译后对应Throwable对象,代表由其他JSP页面抛出的异常对象,只会出现于JSP错误页面(isErrorPage设置为true的JSP页面) |
page | 转译后对应this |
JSP九种内置对象:
一 request对象:
该对象封装了用户提交的信息,通过调用该对象相应的方法可以获取封装的信息, 即使用该对象可以获取用户提交信息。
二 response对象:
对客户的请求做出动态的响应,向客户端发送数据。
三 session对象
1.什么是session:session对象是一个JSP内置对象,它在第一个JSP页面被装载时自动创建,完成会话期管理。
从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话。当一个客户访问一个服务器时,可能会在这个服务器的几个页面之间反复连接,反复刷新一个页面,服务器应当通过某种办法知道这是同一个客户,这就需要session对象。
2.session对象的ID:当一个客户首次访问服务器上的一个JSP页面时,JSP引擎产生一个session对象,同时分配一个String类型的ID号,JSP引擎同时将这个ID号发送到客户端,存放在Cookie中,这样session对象和客户之间就建立了一一对应的关系。当客户再访问连接该服务器的其他页面时,不再分配给客户新的session对象,直到客户关闭浏览器后,服务器端该客户的session对象才取消,并且和客户的会话对应关系消失。当客户重新打开浏览器再连接到该服务器时,服务器为该客户再创建一个新的session对象。
四 aplication对象
1.什么是application:
服务器启动后就产生了这个application对象,当客户在所访问的网站的各个页面之间浏览时,这个application对象都是同一个,直到服务器关闭。但是与session不同的是,所有客户的application对象都是同一个,即所有客户共享这个内置的application对象。
2.application对象常用方法:
(1)public void setAttribute(String key,Object obj): 将参数Object指定的对象obj添加到application对象中,并为添加的对象指定一个索引关键字。
(2)public Object getAttribute(String key): 获取application对象中含有关键字的对象。
五 out对象
out对象是一个输出流,用来向客户端输出数据。out对象用于各种数据的输出。
六 page java.lang.Object
对应this关键字。JSP网页本身
page对象是当前页面转换后的Servlet类的实例。从转换后的Servlet类的代码中,可以看到这种关系:
Object page = this;
在JSP页面中,很少使用page对象。
七 config
javax.servlet. ServletConfig 的实例,该实例代表该JSP 的配置信息。常用的方法有getInitPararneter(String paramNarne) 及getInitPararneternarnes() 等方法。事实上, JSP 页面通常无须配置,也就不存在配置信息。因此,该对象更多地在Servlet 中有效。
八 exception java.lang.Throwable 的实例
该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令page 的isErrorPage 属性为true 时,该对象才可以使用。常用的方法有getMessageO和printStackTraceO等。
javax.servlet.jsp.PageContext 的实例,对象直译时可以称作“页面上下文”对象,代表的是当前页面运行的一些属性,通过此对象可以拿到其他8大对象,使用该对象可以访问页面中的共享数据。常用的方法有getServletContextO和getServletConfigO等。
//使用pageContext 设置属性,该属性默认在page 范围内
pageContext. setAttribute ("page" , "hello") ;
//使用request 设置属性,该属性默认在request 范围内
request. setAttribute ("request" , "hello");
//使用pageContext将属性设置在request 范围中
pageContext.setAttribute("request2" , "hello" , pageContext.REQUEST_SCOPE);
// 使用session将属性设置在session 范围中
session.setAttribute("session" , "hello"l;
//使用pageContext将属性设置在session范围中
pageContext.setAttribute("session2" , "hello" , pageContext.SESSION_SCOPE);
//使用application将属性设置在application范围中
application. setAttribute ("app" , "hello") ;
//使用pageContext 将属性设置在application 范围中
pageContext.setAttribute("app2" , "hello" , pageContext.APPL 工CATION_SCOPE) ;
九、request的API get方法
// 1.req.getAsyncContext();
// return
// 获取异步传输的文本内容
// req.startAsync(req,resp);
// AsyncContext str=req.getAsyncContext();
// System.out.println(str);
// 2.req.getAttribute("");
// return
// 获取指定参数的单个值,在程序中设定的。
// req.setAttribute("uname", "参数值");
// String name=req.getAttribute("uname").toString();
// System.out.println("程序中设定的指定参数值:"+name);
// 3.req.getAttributeNames();
// return
// 获取指定参数的多个值,在程序中设定。
// Enumeration<String> str=req.getAttributeNames();
// while(str.hasMoreElements()){
// System.out.println(str.nextElement());
// }
// 4.req.getAuthType();
// 返回用于保护 servlet 的验证方案的名称。所有 servlet 容器都支持 basic、form 和 client certificate 验证,并且可能还支持 digest 验证。如果没有验证 servlet,则返回 null。
// 返回的值与 CGI 变量 AUTH_TYPE 的值相同。
// return
// 返回静态成员 BASIC_AUTH、FORM_AUTH、CLIENT_CERT_AUTH、DIGEST_AUTH 之一(适用于 == 比较)或返回指示验证方案的特定于容器的字符串,如果没有验证请求,则返回 null。
// String name=req.getAuthType();
//
// System.out.println("返回值为:"+name);
// 5.req.getCharacterEncoding();
// return
// 返回此请求正文中使用的字符编码的名称。null如果请求未指定字符编码,则此方法返回
// String name=req.getCharacterEncoding();
// System.out.println("编码方式为:"+name);
// 6.req.getContentLength();
// return
// 只用于POST请求,表示所发送数据的字节数,body 长度
// int n=req.getContentLength();
// System.out.println("body长度为:"+n);
// 7.req.getContentLengthLong();
// return
// 只用于POST请求,表示所发送数据的字节数,用于数据量非常大时,long八个字节
// long n=req.getContentLengthLong();
// System.out.println("字节数为:"+n);
// 8.req.getContentType();
// return
// 内容类型
// String name=req.getContentType();
// System.out.println("内容类型:"+name);
// 9.req.getContextPath();
// return
// 指定请求 URI 指示请求上下文的那一部分的 String
// String url=req.getContextPath();
// System.out.println("指定URL为:"+url);
// 10.req.getCookies();
// return
// 此请求中包含的所有 Cookie 的数组,如果该请求没有 cookie,则返回 null
// Cookie[] names=req.getCookies();
// for(Cookie n:names){
// System.out.println(n);
// }
// 11.req.getDateHeader(""); 读取指定的报头,然后转换成一个Date值。
// return
// 表示头中指定的日期的 long 值,该日期被表示为自格林威治标准时间 1970 年 1 月 1 日起经过的毫秒数,如果请求中不包含指定的头,则返回 -1
// Throws
// IllegalArgumentException:
// 如果无法将头值转换为日期
// long g=req.getDateHeader("login.jsp");
// System.out.println(g);
// 12.req.getDispatcherType();
// return
// 这个请求的调整度类型
// DispatcherType dpt=req.getDispatcherType();
// System.out.println("这个请求的调整度类型为:"+dpt.toString());
// 13.req.getHeader("");
// return
// 获取指定头信息
// String str=req.getHeader("login.jsp");
// System.out.println(str);
// 14.req.getHeaderNames();
// return
// 随此请求一起发送的所有头名称的枚举;如果该请求没有头,则返回一个空枚举;如果 servlet 容器不允许 servlet 使用此方法,则返回 null
// Enumeration<String> str=req.getHeaderNames();
// while(str.hasMoreElements()){
// System.out.println(str.nextElement());
// }
// 15.req.getHeaders("");
// return
// 包含请求头的值的 Enumeration。如果该请求不包含任何具有该名称的头,则返回一个空枚举。如果容器不允许访问头信息,则返回 null
// String str=req.getHeader("login.jsp");
// System.out.println(str);
// 16.req.getInputStream();获取请求内容,可以获取post方法在网页中通过send传递的内容,但是要通过InputStreamReader实例化
// return
// 返回一个输入流用来从请求体读取二进制数据。
// ServletInputStream str=req.getInputStream();
// System.out.println(str.toString());
// 17.req.getIntHeader("");
// return
// 表示请求头的值的整数,如果该请求没有此名称的头,则返回 -1
// int n=req.getIntHeader("login.jsp");
// System.out.println(n);
// 18.req.getLocalAddr();
// return
// 返回web服务器的IP地址
// String name=req.getLocalAddr();
// System.out.println("WEB服务器的ip地址为:"+name);
// 19.req.getLocale();
// return
// 基于 Accept-Language 头,返回客户端将用来接受内容的首选 Locale 客户端语言环境
// Locale str=req.getLocale();
// System.out.println(str.toString());
// 20.req.getLocales();
// return
// 返回所有的语言环境
// Enumeration<Locale> str=req.getLocales();
// while(str.hasMoreElements()){
// System.out.println(str.hashCode());
// }
// 21.req.getLocalName();
// return
// 返回WEB服务器的主机名
// String name=req.getLocalName();
// System.out.println(name);
// 22.req.getLocalPort();
// return
// 获取端口号
// int name=req.getLocalPort();
// System.out.println("端口号:"+name);
// 23.req.getMapping();
// return
// 这个请求的调整度类型
// Mapping m=req.getMapping();
// System.out.println("这个请求的调整度类型:"+m);
// 24.req.getMethod();
// return
// 获取客户端的请求方式
// String name=req.getMethod();
// System.out.println("客户端的请求方式:"+name);
// 25.req.getParameter("");
// return
// 获取指定名称的请求参值的请求参数(单值)
// String name=req.getParameter("uname");
// System.out.println("指定参数的值为"+name);
// 26.req.getParameterMap();
// return
// 一个不可变的java.util.Map,其中包含参数名称作为键和参数值作为映射值。参数图中的键的类型为String。参数映射中的值为String数组。
Map<String, String[]> map=(Map<String, String[]>) req.getParameterMap();
// System.out.println(map.toString());
// 27.req.getParameterNames();
// return
// 获取指定名称的请求参值的请求参数(多值)
// Enumeration<String> str=req.getParameterNames();
// while(str.hasMoreElements()){
// System.out.println(str.nextElement());
// }
// 28.req.getParameterValues("");
// return
// 返回一个包含String给定请求参数的所有值的对象数组,或者 null该参数不存在。
// String[] str=req.getParameterValues("uname");
// for(String s:str){
// System.out.println(s);
// }
// 29.req.getPart("");
// return
// 获取Part给定的名称
Part p=req.getPart("file");
// Part p=req.getPart("uname");
// System.out.println(p.toString());
// 30.req.getParts();
// return
// 获取Part此请求的所有组件,前提是它是类型multipart/form-data。
// Collection<Part> str=req.getParts();
// System.out.println(str.toString());
// 31.req.getPathInfo();
// return
// 由 Web 容器解码的 String,用于指定额外路径信息,这些信息在请求 URL 中跟随在 servlet 路径之后但在查询字符串之前;如果该 URL 没有任何额外路径信息,则返回 null
// String name=req.getPathInfo();
// System.out.println(name);
// 32.req.getPathTranslated();
// return
// 指定实际路径的 String,如果 URL 没有额外路径信息,则返回 null
// String url=req.getPathTranslated();
// System.out.println("指定实际路径的String为:"+url);
// 33.req.getProtocol();
// return
// 返回网络协议
// String str=req.getProtocol();
// System.out.println("网络协议为:"+str);
// 34.req.getPushBuilder();
// return
// 获取PushBuilder 。每次调用此方法将返回一个基于当前的PushBuilder的新实例HttpServletRequest。返回的PushBuilder的任何突变都不会反映在未来的回报上。
// PushBuilder str=req.getPushBuilder();
// System.out.println(str.toString());
// 35.req.getQueryString();
// return
// 获取参数部门,即地址栏问号后面的部分:username=zhangsan
// String name=req.getQueryString();
// System.out.println("地址栏问号后面的为:"+name);
// 36.req.getReader();
// return
// 一个BufferedReader包含请求的正文
// BufferedReader str=req.getReader();
// System.out.println(str.toString());
// 37.req.getRealPath("");(!!!!!!!!不用写!!!!!!!)
// return
// 返回与虚拟路径相对应的真实路径,如果因为某种原因,这一过程不能进行,该方法将返回一个空值。
// 38.req.getRemoteAddr();获取客户端的ip地址
// return
// String包含发送请求的客户端的IP地址
// String ip=req.getRemoteAddr();
// System.out.println("客户端ip地址"+ip);
// 39.req.getRemoteHost();
// return
// 返回发送请求的客户端或最后一个代理的完全限定名称。
// String name=req.getRemoteHost();
// System.out.println("完全限定名称:"+name);
// 40.req.getRemotePort();
// return
// 返回客户机所使用的网络端口号
// int name=req.getRemotePort();
// System.out.println("网络端口号:"+name);
// 41.req.getRemoteUser();
// return
// a String指定进行该请求null 的用户的登录,或者用户登录不知道
// String user=req.getRemoteUser();
// System.out.println("用户的登录:"+user);
// 42.req.getRequestDispatcher("");
// return
// RequestDispatcher作为资源在指定路径的包装器的对象,或者nullservlet容器不能返回的对象RequestDispatcher
// RequestDispatcher str=req.getRequestDispatcher("login.jsp");
// System.out.println(str.toString());
// 43.req.getRequestedSessionId();
// return
// 指定会话 ID 的 String,如果该请求没有指定会话 ID,则返回 null
// String id=req.getRequestedSessionId();
// System.out.println("指定会话的id为:"+id);
// 44.req.getRequestURI();
// return
// 获取请求的URL
// String name=req.getRequestURI();
// System.out.println("获取请求的URL为:"+name);
// 45.req.getRequestURL();
// return
// 包含 URL 从协议名称一直到查询字符串的那一部分的 String
// StringBuffer str=req.getRequestURL();
// System.out.println(str.toString());
// 46.req.getScheme();
// return
// 返回请求所使用的URL的模式。
// String name=req.getScheme();
// System.out.println("URL模式为:"+name);
// 47.req.getServerName();获取服务器名:localhost
// String str=req.getServerName();
// System.out.println("服务器名:"+str);
// 48.req.getServerPort();
// return
// 获取服务器端口:8080
// int n=req.getServerPort();
// System.out.println("服务器端口为:"+n);
// 49.req.getServletContext();
// return
// 获取该servlet的相关信息
// ServletContext ss=req.getServletContext();
// System.out.println("servlet相关信息:"+ss.toString());
// 50.req.getServletPath();URL中调用Servlet的那一部分,不包含附加路径信息和查询字符串。
// return
// 获取servlet路径:/
// String name=req.getServletPath();
// System.out.println("servlet路径:"+name);
// 51.req.getSession();
// return
// 与此请求关联的 HttpSession
// HttpSession hh=req.getSession();
// System.out.println("关联的httpsession为:"+hh.toString());
// 52.req.getSession(true);
// return
// 与此请求关联的 HttpSession,如果 create 为 false,并且该请求没有有效会话,则返回 null
// 53.req.getUserPrincipal();
// return
// 包含发出此请求的用户的名称的 java.security.Principal;如果用户没有经过验证,则返回 null
// String name=req.getUserPrincipal().toString();
// System.out.println(name);