一、Servlet简介:
1、什么是Servlet
Servlet是运行在服务器端的Java小程序,是sun公司提供的一套规范,用来处理客户端的请求,响应给浏览器的动态资源。Servlet的实质是Java代码,通过Java的API动态的向客户端输出内容。
Servlet规范包含三个技术点:servlet技术 filter技术(过滤器) listener技术(监听器)
2、Servlet快速入门
实现步骤:
1)创建类实现Servlet接口
2)覆盖尚未实现的方法
3)在web.xml种进行servlet的配置
但在实际开发中,不会直接去实现servlet接口,因为那要需要覆盖的方法太多,我们一般创建类实现HttpServlet
实现步骤:
二、Servlet的API(生命周期)
Servlet接口中的方法
1)init(ServletConfig config) --- 执行一次,并且在servlet第一次被访问时执行(servlet对象创建时执行)
ServletConfig可以获取servlet的name以及一些初始化参数,也可以获取ServletContext对象
2)service(SerevletRequest request, ServletResponse response) --- 每次访问都会执行
ServletRequest代表请求 ServletResponse代表响应
3)destory() --- servlet销毁时执行
总结:Servlet对象默认第一次访问时创建,服务器关闭时销毁,当这个对象创建时会调用init方法,当该对象销毁时会调用destory方法,每次访问时都会调用service方法。
Servlet对象的生命周期
1)何时被创建:默认第一次访问servlet时创建该对象;
2)合适被销毁:服务器关闭servlet就销毁了
3)每次访问必须执行的方法:service方法
HttpServlet类方法
1)init()
2)doGet(HttpServletRequest request, HttpServletResponse response)
3)doPost(HttpServletResponse response, HttpServletResponse response)
4)destory()
三、Servlet配置
1、基本配置
<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>全类名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>/aaa</url-parttern>
</servlet-mapping>
其中url-pattern的配置方式:
1)完全匹配 访问的资源与配置的资源完全相同才能访问到 如上面的代码块
2)目录匹配 格式:/虚拟目录../* *代表任意 <url-pattern>/aaa/bbb/ccc/*</url-pattren>
3)扩展名匹配 格式:*.扩展名 <url-pattern>*.abcd</url-pattern>
注意:第二种和第三种不要混用,/aaa/bbb/ccc/*.abcd时错误的
2、服务器启动实例化servlet配置
servlet何时创建:默认第一次访问时创建,为什么时默认情况下时第一次访问时创建;在servlet配置时,加上<load-on-startup>servlet对象在服务器启动时就创建。 例如:<load-on-startup>3</load-on-startup>数字代表优先级 数字越小优先级越高 如果有<init-param>配置,则<load-on-startup>需要写在<init-param>后面。
3、缺省servlet
可以将url-pattern配置一个/,代表该servlet是缺省的servlet 。什么是缺省的servlet -- 当你访问的资源地址和所有的servlet都不匹配时,缺省的servlet负责响应此请求。
其实web应用中所有的资源响应都是servlet负责,包括静态资源
4、欢迎界面
欢迎界面由web.xml配置,如果项目的web.xml没有配置,则Tomcat的配置文件发生作用。
四、ServletContext对象
1、什么时ServletContext对象
ServletConetxt对象代表一个web应用的上下文对象,ServletContext对象内部封装的是该web应用的信息,ServletContext对象一个web应用只有一个。
ServletContext对象的生命周期
创建:该web应用被加载(服务启动或发布web应用,前提是服务器为启动状态)
销毁:web应用被加载(服务器关闭,移除该web应用)
2、怎么获取ServletContext对象
1)ServletContext servletContext = config.getServletContext();
2)ServletContext servletContext = this.getServletContext();
3、ServletContext的作用
1)获得web应用全局的初始化参数
web.xml中配置全局初始化参数
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
通过context对象获得参数
ServletContext context = getServletContext();
String initParameter = context.getInitParameter("driver");
2)获得web应用中任何资源的绝对路径(重点)
String path = context.getRealPath(相对于该web应用的相对地址);
例子:获取webcontent目录下的a.txt的绝对路径:context.getRealPath(/a.txt),/可以不写;
获取WEB-INF下的b.txt绝对地址:context.getRealPath(/WEB-INF/b.txt); 外网不能直接访问该目录 但是在servlet中可以访问;
获取src目录下的c.txt绝对地址:context.getRealPath(/WEB-INF/classes/c.txt);
获取项目下的d.txt绝对地址:是无法获取的 因为项目下的文件没有发送的tomcat中;
注意:在读取src目录下的文件时,可以通过类加载器;因为src目录下的文件会被发送到classes目录下,而类加载器是专业加载classes目录下的文件:ContextServlet.class.getClassLoader().getResource("c.txt").getpath();
3)ServletContext是一个域对象(重点)
什么是域对象---存储数据的区域就是域对象;ServletContext域对象的作用范围:整个web应用(所有的web资源都可以随意向servletContext域中存取数据,数据可以共享)。
域对象的通用用法:
setAtrribute(String name,Object object)
getAtrribute(String name)
removeAtrribute(String name)
案例:登陆,并记录登陆成功次数
1、导入c3p0,mysql以及DButils架包
2、在src下进行c3p0(c3p0-config.xml)的配置,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="user">root</property>
<property name="password">ws2582004030</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web13</property>
</default-config>
</c3p0-config>
3、新建utils包,新建DBUtils工具类,代码如下:
public class DataSourceUtils {
private static DataSource dataSource = new ComboPooledDataSource();
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
// 直接可以获取一个连接池
public static DataSource getDataSource() {
return dataSource;
}
// 获取连接对象
public static Connection getConnection() throws SQLException {
Connection con = tl.get();
if (con == null) {
con = dataSource.getConnection();
tl.set(con);
}
return con;
}
// 开启事务
public static void startTransaction() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.setAutoCommit(false);
}
}
// 事务回滚
public static void rollback() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.rollback();
}
}
// 提交并且 关闭资源及从ThreadLocall中释放
public static void commitAndRelease() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.commit(); // 事务提交
con.close();// 关闭资源
tl.remove();// 从线程绑定中移除
}
}
// 关闭资源方法
public static void closeConnection() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.close();
}
}
public static void closeStatement(Statement st) throws SQLException {
if (st != null) {
st.close();
}
}
public static void closeResultSet(ResultSet rs) throws SQLException {
if (rs != null) {
rs.close();
}
}
}
4、新建domain实体包,新建User类,字段和数据库保持一致,代码如下:
public class User {
private int id;
private String username;
private String password;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + "]";
}
}
5、新建登陆Servlet,代码如下:
public class LoginServlet extends HttpServlet {
//完成登陆 记录登陆成功次数功能
@Override
public void init() throws ServletException {
//在ServletContext中存一个数据
int count = 0;
this.getServletContext().setAttribute("count", count);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
String sql = "select * from user where username=? and password=?";
User user = null;
try {
user = runner.query(sql, new BeanHandler<User>(User.class) , username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(user != null){
//从ServletContext中取出域数据+1
ServletContext context = this.getServletContext();
Integer count = (Integer) context.getAttribute("count");
count ++;
context.setAttribute("count", count);
response.getWriter().write(user.getUsername() + "you are " + count + " login person");
} else {
response.getWriter().write("login failed...");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
6、新建login.html,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/WEB13/loginServlet" method="POST"//>
<input name="username" type="text"><br/>
<input name="password" type="password"><br/>
<input type="submit" value="登陆">
</form>
</body>
</html>