1Servlet简介
Servlet 是运行在服务端的Java小程序,是sun公司提供的一套规范(接口),
用来处理客户端请求、响应给浏览器的动态资源。
servlet的实质就是java代码,通过java的API 动态的向客户端输出内容。
2 Servlet快速入门
实现步骤:
1)创建类实现Servlet接口
2)覆盖尚未实现的方法---重点实现service方法
3)在web.xml进行servlet的配置
例:
建一个Dynamic Web Project
建一个MyServlet类实现Servlet接口,并重写方法(主要是service方法)
配置web.xml文件:
将项目添加到服务器并启动,
浏览器访问:http://localhost:8080/20180108Test/MyServlet
图示描述整个访问过程:
浏览器发送请求后,Tomcat引擎会先解析地址:找到
http://localhost:8080/20180108Test/MyServlet 这个地址中的/MyServlet,然后到web.xml中找这个url-pattern
然后找到servlet-name
再由这个name找到servlet的servlet-name
再找到servlet-class
然后创建servlet对象,再创建请求对象(把请求信息封装到对象中),和响应对象,并把对象传入到service方法中。
3 Servlet的API
3.1Servlet接口中的方法
1)init(ServletConfig arg0)方法
在servlet对象创建的时候执行对象创建时执行
ServletConfig是该servlet对象的配置信息,
方法:获取servlet名称,获得初始化参数,获得ServletContext对象
2)service(ServletRequest arg0, ServletResponse arg1)方法
每次请求都会执行。
ServletRequest:代表请求的对象,内部封装的是http请求的信息
ServletResponse:代表响应的对象,要封装的是响应的信息
3)destroy()方法
servlet销毁时执行
3.2 Servlet的生命周期
1)Servlet何时创建
默认(服务器启动时)第一次访问servlet时创建该对象
2)Servlet何时销毁
服务器关闭servlet就销毁了
3)每次访问必然执行的方法
service(ServletRequest req, ServletResponse res)方法
例:web.xml添加上一个参数(随意写的值)
MyServlet修改为:
package demo01; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class MyServlet implements Servlet{ @Override public void destroy() { System.out.println("servlet销毁了"); } @Override public ServletConfig getServletConfig() { // TODO Auto-generated method stub return null; } @Override public String getServletInfo() { // TODO Auto-generated method stub return null; } @Override public void init(ServletConfig arg0) throws ServletException { //1.获取servlet名称 String name=arg0.getServletName(); System.out.println("名字是"+name+"的servlet对象创建了"); //2.获得初始化参数 String value=arg0.getInitParameter("url"); System.out.println("初始化参数url是"+value); //3.获得ServletContext对象 ServletContext context=arg0.getServletContext(); System.out.println("ServletContext对象是"+context); } @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("service正在运行"); } }
再重新部署,启动,访问两遍:
可以看到对象只创建了一个,init方法只运行一次,而service方法是每请求一次,就调用一次。
服务器执行Stop,
4 Servlet的配置
4.1 url-pattern的配置方式
1)完全匹配 访问的资源与配置的资源完全相同才能访问到
2)目录匹配 格式:/虚拟的目录../* *代表任意
可用于分类
3)扩展名匹配 格式:*.扩展名
注意:第二种与第三种不要混用,会造成不确定性, /aaa/bbb/*.abcd(错误的)
4.2服务器启动实例化Servlet配置
1)Servlet默认第一次访问时创建,可以修改成在对象在服务器启动时就创建,
加一个<load-on-startup>任意正整数</load-on-startup>
数字代表优先级,越小优先级越高,但不要设为1
改完后,启动时就创建了:
2)缺省Servlet(默认值)
将url-pattern配置一个/,代表该servlet是缺省的servlet。
当访问资源地址时,所有的servlet都不匹配时,缺省的servlet负责处理。
例:
再建一个class,DefaultServlet,service方法:
配置web.xml:
访问:
注意:
访问jsp不行,因为服务器conf目录下有一个web.xml,里面写了.jsp的配置。
当本地的web.xml中没有时,会去服务器上的找
所以一般不配缺省servlet。
4.3欢迎页面
就是配置的首页,当只访问工程时,依次找这些页面
这上面没有,再去conf目录下的web.xml找
例:
5 HttpServlet
在实际开发中,不会直接去实现Servlet接口,因为需要覆盖的方法太多,一般创建类继承HttpServlet。
5.1实现步骤
1)创建类继承HttpServlet类
2)覆盖doGet和doPost方法
3)在web.xml中进行servlet的配置
doGet和doPost方法实际上就是service方法
5.2添加Servlet模板
Window---Preferences
然后,new一个servlet,crtl+A删掉所有内容。再Alt+/,就会出现自己的模板提示了
6 ServletContext对象
6.1概述
ServletContext是一个web应用的环境(上下文)对象,代表web项目的对象,
内部封装的是该web应用的信息,一个web应用只有一个ServletContext对象,
但是一个web应用有多个servlet对象
6.2生命周期
创建:该web应用被加载(服务器启动或发布web应用(前提,服务器启动状态))
销毁:web应用被卸载(服务器关闭,remove移除该web应用)
6.3获得ServletContext对象
1)ServletContext servletContext = config.getServletContext();
2)ServletContext servletContext = this.getServletContext();(常用)
Tips:GenericServlet类中有getServletConfig()方法返回ServletContext对象,所以子类可以直接用
6.4 ServletContext的作用
1)获得web应用全局的初始化参数
用getInitParameter(“参数名”)方法获取
Tips:这个参数是全局的。上面3.1示例中也有一个参数,那个是servlet中的参数
2)获得web应用中任何资源的绝对路径
例:
在WebContent上建一个a.txt文件
在WEB-INF上建一个b.txt
在src上建一个c.txt
在工程上建一个d.txt
建一个PathServlet:
package com.zyx.demo02; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PathServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取文件绝对路径 ServletContext context=this.getServletContext(); String patha=context.getRealPath("a.txt"); String pathb=context.getRealPath("WEB-INF/b.txt"); String pathc=context.getRealPath("WEB-INF/classes/c.txt"); System.out.println(patha); System.out.println(pathb); System.out.println(pathc); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
但是工程上的文件是获取不到的,因为不会被部署到服务器上。
3)ServletContext是一个域对象
相当于一个容器
作用范围:整个web应用
所有的web资源都可以随意向 servletcontext域中存取数据,数据可以共享
通用的方法:
setAtrribute(String name,Object obj);
getAttribute(String name);
removeAttribute(String name);
如果有重复的key值会覆盖
例:
package com.zyx.demo03; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取ServletContext对象 ServletContext context=getServletContext(); //往域对象中设置值 context.setAttribute("name", "张三"); context.setAttribute("name", "李四"); //张三就被覆盖了 } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.zyx.demo03; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取ServletContext对象 ServletContext context=getServletContext(); //从域对象中取值 String name=(String)context.getAttribute("name"); System.out.println(name); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
6.5登录并记录登录次数示例
采取分层分包方式,注意驱动包,工具包,Properties配置文件等。
jsp文件设置编码:
jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>用户登录</title> </head> <body> <form action="/WEB20190108/LoginServlet" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="登录"> </form> </body> </html>
LoginServlet:
package com.zyx.web; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.zyx.service.UserService; public class LoginServlet extends HttpServlet { private UserService userService=new UserService(); //只运行一次 public void init() throws ServletException { //获取ServletContext对象 ServletContext context=getServletContext(); //初始化计数器 int count=0; //将计数器放在context对象中 context.setAttribute("count", count); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取前端提交的用户名和密码 String username=request.getParameter("username"); String password=request.getParameter("password"); //2.调用service层方法验证 int count=userService.loginUser(username, password); if(count>0){ //获取ServletContext对象 ServletContext context=getServletContext(); //获得计数器 int num=(int)context.getAttribute("count"); num++; //更新计数器 context.setAttribute("count", num); response.getWriter().write("you art the "+num+"person success"); }else{ response.getWriter().write("faile"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Service和Dao层代码就不贴了,与之前做jdbc分包那里一致。
再进一次: