6、Servlet 6.1Servlet简介这里是狂神的哔哩哔哩地址:https://www.bilibili.com/video/BV12J411M7Sj?p=30&spm_id_from=pageDriver
-
Servlet就是孙公司开发的动态web的一门技术
-
Sun在这些API中提供了一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
- 编写一个类,实现Servlet接口
- 把开发好的Java类部署到web服务器中
把实现了Servlet接口的Java程序叫做,Servlet
Servlet接口在Sun公司有两个实现类 HttpServlet
- 构建一个普通的Maven项目,删掉里面的src目录,在这个项目里面建立Moudel;这个空的工程就是Maven主工程。
- 关于Maven父子工程的理解:
父项目中
javaweb01
父项目中的的Java子项目可以直接使用
son extends father
- Maven环境优化
- 修改web.xml为最新的
- 将Maven的结构搭建完整
- 编写一个Servlet程序
- 编写一个普通类
- 实现servlet接口,直接集成HttpServlet
package com.wukong;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现不同的方式,可以直接调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();//响应流
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
- 编写Servlet的映射
为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接Web服务器,我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径。
hello com.wukong.HelloServlet hello hello
- 配置Tomcat
注意:配置项目发布的路径就可以了
- 启动测试
Servet是由Web服务器调用,web服务器在收到浏览器请求之后,会:
6.4Mapping- 一个请求可以指定一个映射路径
- 一个请求可以指定多个映射路径
- 一个请求可以指定通用个映射路径
- 指定一些后缀前缀等
- 优先级问题
- 固有的映射路径优先级最高
- 如果找不到就会走默认的处理请求
error com.wukong.ErrorServlet error @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); System.out.println("filter执行前...."); chain.doFilter(request,response);//让我们的请求继续走,如果不写程序到这就停止了 System.out.println("filter执行后...."); } //web服务器关闭的时候才会销毁 //销毁 @Override public void destroy() { System.out.println("destroy成功!"); } }
- 在web.xml中配置Filter
12、监听器filterDemo01 com.wukong.filter.FilterDemo01 filterDemo01 /servlet/*
实现一个监听器的接口:
-
编写一个监听器:实现监听器的接口
//统计网站在线人数:统计session public class OnlineCountListener implements HttpSessionListener { //创建Session监听;看你的一举一动 //一旦创建Session就会触发一次这个事件 @Override public void sessionCreated(HttpSessionEvent se) { ServletContext context = se.getSession().getServletContext(); Integer onlineCount = (Integer) context.getAttribute("OnlineCount"); if (onlineCount==null){ onlineCount = new Integer(1); }else{ int count = onlineCount.intValue(); onlineCount = new Integer(count+1); } System.out.println(se.getSession().getId()); context.setAttribute("OnlineCount",onlineCount); } //销毁session监听 //一旦session销毁就会触发这个事件 @Override public void sessionDestroyed(HttpSessionEvent se) { ServletContext context = se.getSession().getServletContext(); Integer onlineCount = (Integer) context.getAttribute("OnlineCount"); if (onlineCount==null){ onlineCount = new Integer(0); }else{ int count = onlineCount.intValue(); onlineCount = new Integer(count-1); } context.setAttribute("OnlineCount",onlineCount); } -
在web.xml中注册监听器
com.wukong.listener.OnlineCountListener
13、过滤器、监听器的常见应用
用户登录之后才能进入主页,用户注销之后不能进入主页了!
- 用户登录之后,向Session中放入数据,
- 进入主页的时候要判断用户是否已经登录,要求:在过滤器中实现
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request1 = (HttpServletRequest) request;
HttpServletResponse response1 = (HttpServletResponse) response;
Object user_session;
if(request1.getSession().getAttribute("USER_SESSION")==null){
((HttpServletResponse) response).sendRedirect("/error.jsp");
}
chain.doFilter(request,response);
}
设置字符编码,过滤器实现
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
System.out.println("filter执行前....");
chain.doFilter(request,response);//让我们的请求继续走,如果不写程序到这就停止了
System.out.println("filter执行后....");
}
JDBC
什么是JDBC:java链接数据库
需要jar包的支持:
- java.sql
- javax.sql
- mysql-conneter-java (链接驱动)
创建数据库表
CREATE TABLE `user` ( `id` int(4) NOT NULL, `name` varchar(40) NOT NULL, `email` varchar(40) NOT NULL, `birthday` date NOT NULL, `password` varchar(40) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 INSERT INTO `user`(id,`name`,`password`,email,birthday) VALUES(1,'张三','123456','zs@qq.com','2000-01-01'); INSERT INTO `user`(id,`name`,`password`,email,birthday) VALUES(2,'李四','123456','zs@qq.com','2000-01-01'); INSERT INTO `user`(id,`name`,`password`,email,birthday) VALUES(3,'王五','123456','zs@qq.com','2000-01-01');
导入数据库依赖
mysql
mysql-connector-java
5.1.47
JDBC 固定步骤
public class TestJDBC {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.链接数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.向数据库发送SQL的对象 Statement:CURD
Statement statement = connection.createStatement();
//4.编写SQL语句
String sql = "select * from jdbc.user";
//5.执行sql
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
System.out.println("id="+resultSet.getObject("id"));
System.out.println("name="+resultSet.getObject("name"));
System.out.println("password="+resultSet.getObject("password"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("birthday="+resultSet.getObject("birthday"));
}
//6.关闭链接,释放资源 先开后关
resultSet.close();
statement.close();
connection.close();
}
}
预编译sql
public class TestJDBC2 {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.链接数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.编写SQL语句
String sql = "replace into user(id, name, email, birthday, password) VALUES (?,?,?,?,?)";
//4.预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,1);
preparedStatement.setString(2,"悟空");
preparedStatement.setString(3,"9222@qcom");
preparedStatement.setObject(4,new java.sql.Date(new java.util.Date().getTime()));
preparedStatement.setString(5,"654321");
//受影响的行数 增删改都是用executeUpdate
//int i = statement.executeUpdate(sql);
//5.执行sql
int i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("插入成功");
}
//6.关闭链接,释放资源 先开后关
preparedStatement.close();
connection.close();
}
}
事务
要么都成功,要么都失败!
ACID原则:保证数据的安全。
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
转账 A:1000 B:1000
A(900) -100—> B(1100)
Jnit单元测试
依赖
junit junit 4.12 test
简单使用:
- @Text注解只在方法上有效,加了 这个方法的都可以直接运行
public class TestJDBC3 {
@Test
public void test(){
System.out.println("hello");
}
}
搭建一个环境测试事务
public class TestJDBC3 {
@Test
public void test() throws SQLException, ClassNotFoundException {
Connection connection = null;
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=true";
String username = "root";
String password = "123456";
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.链接数据库
connection = DriverManager.getConnection(url, username, password);
//通知数据库开启事务 false 是开启事务
connection.setAutoCommit(false);
String sql = "update jdbc.account set money = money -100 where name = 'A'";
connection.prepareStatement(sql).executeUpdate();
//制造错误
//int i = 1 / 0;
String sql2 = "update jdbc.account set money = money +100 where name = 'B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上两条sql 都执行成功了就提交事务
System.out.println("success");
} catch (Exception e) {
try {
connection.rollback();//如果出现异常就通知数据库回滚事务
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
connection.close();
}
}
}



