web入门案例
简述
下面我们来构建一个小型web项目,实现登录功能和展示所有用户功能。
步骤
首先我们来创建个数据库叫companydb,创建个表叫admin设置字段及类型
CREATE DATABASE companydb; USE companydb; CREATE TABLE admin( username VARCHAR(20) PRIMARY KEY NOT NULL, PASSWORD VARCHAR(20) NOT NULL, phone VARCHAR(11) NOT NULL, address VARCHAR(20) NOT NULL )CHARSET=utf8;
然后我们插入数据
INSERT INTO admin VALUES('hjj','123456','12345678901','广外');
接着我们创建一个普通的web项目,教程——https://www.cnblogs.com/qq2210446939/p/13922657.html
我们导入几个基本的jar包
然后在src目录下创建我们的数据库配置文件,写上驱动用户密码连接池配置等信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/companydb?useUnicode=tru&characterEncoding=UTF-8 username=root password=123456 #初始连接数量 initialSize=10 #最大活动连接数量 maxActive=20 #最小空闲连接数量 minIdle=5 #超时时限 maxWait=3000
然后我们创建一个servletProject包,并在里面创建utils包,在包里创建我们的DbUtils工具类
工具类方便我们操作和数据库的连接,事务的提交回滚等操作,当然如果我们用mybatis框架的话就不用写,框架帮我们弄好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.utils; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /** * @author Layton * @version 1.0 * @date 2020/11/20 18:42 */ public class DbUtils { //数据库连接池 private static DruidDataSource ds; // private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<>(); static { Properties properties = new Properties(); InputStream inputStream = DbUtils.class.getResourceAsStream("/database.properties"); try { properties.load(inputStream); ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() { //从连接池里拿连接 Connection connection = THREAD_LOCAL.get(); try { if (connection == null) { //新建连接并放入连接池 connection = ds.getConnection(); THREAD_LOCAL.set(connection); } } catch (SQLException e) { e.printStackTrace(); } return connection; } /** * 开启事务 */ public static void begin() { Connection connection = null; connection = getConnection(); try { connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } /** * 提交事务 */ public static void commit() { Connection connection = null; try { connection = getConnection(); connection.commit(); } catch (SQLException e) { e.printStackTrace(); } finally { //statement和result参数都为空 closeAll(connection, null, null); } } public static void rollback() { Connection connection = null; try { connection = getConnection(); connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } finally { //statement和ResultSet参数都为空 closeAll(connection, null, null); } } public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); THREAD_LOCAL.remove(); } } catch (SQLException e) { e.printStackTrace(); } } }
接着我们创建一个entity包用来存实体类,里面生成我们的admin实体类
我们在admin类中生成构造、get、set、tostring方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.entity; public class Admin { private String username; private String password; private String phone; private String address; public Admin() { } public Admin(String username, String password, String phone, String address) { this.username = username; this.password = password; this.phone = phone; this.address = address; } 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 getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Admin{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", phone='" + phone + '\'' + ", address='" + address + '\'' + '}'; } }
接着我们创建一个dao包,表示持久层,在该包创建一个IAdminDao接口
里面写上和数据库发生交互的方法,增删查改等
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.dao; import com.hjj.servletProject.entity.Admin; import java.util.List; public interface IAdminDao { //插入 public int insert(Admin admin); //删除 int delete(String username); //更新 int update(Admin admin); //查询一个 Admin select(String username); //查询所有 List<Admin> selectAll(); }
然后我们在dao包里创建一个dao层的实现类,继承IAdminDao接口,通过queryRunner实现我们的查询一个和查询所有方法,增删改这里先不写
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.dao.impl; import com.hjj.servletProject.dao.IAdminDao; import com.hjj.servletProject.entity.Admin; import com.hjj.servletProject.utils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import java.sql.SQLException; import java.util.List; /** * @author Layton * @version 1.0 * @date 2020/11/20 19:39 */ public class IAdminDaoImpl implements IAdminDao { private QueryRunner queryRunner = new QueryRunner(); @Override public int insert(Admin admin) { return 0; } @Override public int delete(String username) { return 0; } @Override public int update(Admin admin) { return 0; } @Override public Admin select(String username) { try { Admin admin = queryRunner.query(DbUtils.getConnection(), "select * from admin where username = ?;", new BeanHandler<Admin>(Admin.class), username); return admin; } catch (SQLException e) { e.printStackTrace(); } return null; } @Override public List<Admin> selectAll() { List<Admin> admins = null; try { admins = queryRunner.query(DbUtils.getConnection(),"select * from admin",new BeanListHandler<Admin>(Admin.class)); return admins; } catch (SQLException e) { e.printStackTrace(); } return null; } }
然后我们创建我们的service层,放上我们的AdminServie接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.service; import com.hjj.servletProject.entity.Admin; import java.util.List; /** * @author Layton * @version 1.0 * @date 2020/11/21 0:22 */ public interface AdminService { /** * 登录 * @param username * @param password * @return */ public Admin Login(String username, String password); /** * 展示所有用户 * @return */ public List<Admin> showAllAdmin(); }
同样的添加service的实现类
里面实现我们的登录方法和显示所有用户方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.service.impl; import com.hjj.servletProject.dao.IAdminDao; import com.hjj.servletProject.dao.impl.IAdminDaoImpl; import com.hjj.servletProject.entity.Admin; import com.hjj.servletProject.service.AdminService; import com.hjj.servletProject.utils.DbUtils; import java.util.List; /** * @author Layton * @version 1.0 * @date 2020/11/21 0:28 */ public class AdminServiceImpl implements AdminService { //dao层的接口对象 private IAdminDao adminDao = new IAdminDaoImpl(); @Override public Admin Login(String username, String password) { Admin result = null; try { //开始事务 DbUtils.begin(); Admin admin = adminDao.select(username); if (admin != null) { //用户存在,接下来验证密码 if (admin.getPassword().equals(password)) { //查询到的对象密码和传过来的密码相等 result = admin; } } //提交事务 DbUtils.commit(); } catch (Exception e) { e.printStackTrace(); //出现异常则回滚 DbUtils.rollback(); } return result; } @Override public List<Admin> showAllAdmin() { return null; } }
接着我们创建servlet包,在包里创建我们的LoginServlet类继承HttpServlet,同时重写doget、dopost方法完成登录
现在我们让doPost调用doGet,在doget里写响应过程
分为以下几步:设置字符集、接受参数、调用service层业务、分结果返回页面
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.servlet; import com.hjj.servletProject.entity.Admin; import com.hjj.servletProject.service.AdminService; import com.hjj.servletProject.service.impl.AdminServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @author Layton * @version 1.0 * @date 2020/11/21 15:36 */ @WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); //1.收参 String username = req.getParameter("username"); String password = req.getParameter("password"); //2.调用业务逻辑 AdminService adminService = new AdminServiceImpl(); Admin admin = adminService.Login(username,password); //3.处理结果 PrintWriter pw = resp.getWriter(); if(admin != null){ //响应给客户端一个结果页面,显示登录成功 pw.println("<html>"); pw.println("<head>"); pw.println("<meta charset='UTF-8'>"); pw.println("<title>结果页面</title>"); pw.println("</head>"); pw.println("<body>"); pw.println("<h1>登录成功</h1>"); pw.println("</body>"); pw.println("</html>"); }else{ //响应给客户端一个结果页面,显示登录失败 pw.println("<html>"); pw.println("<head>"); pw.println("<meta charset='UTF-8'>"); pw.println("<title>结果页面</title>"); pw.println("</head>"); pw.println("<body>"); pw.println("<h1>登录失败</h1>"); pw.println("</body>"); pw.println("</html>"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
最后我们在web目录添加个login的html文件,里面写上我们的表单,设置好name以便于传递参数给我们的LoginServlet
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <form action="/My_Servlet_war_exploded/login" method="post"> 用户名:<input type="text" name="username"> <br> 密码:<input type="password" name="password"> <br> <input type="submit" value="登录"> </form> </body> </html>
至此我们的登录需求已经完成了,我们启动tomcat服务器,在Url里输入login.html就可以跳转到登录界面,输入正确的用户名和密码即可提交到我们的LoginServlet,LoginServlet会接受参数并调用service业务,根据业务结果也就是用户名密码对不对返回不同的结果
接着我们实现展示所有用户功能,我们先写业务层逻辑代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Override public List<Admin> showAllAdmin() { List<Admin> admins = null; try { DbUtils.begin(); admins = adminDao.selectAll(); DbUtils.commit(); } catch (Exception e) { e.printStackTrace(); DbUtils.rollback(); } return admins; }
需要注意的是,无论有没有查到东西,都会返回一个admins列表
接着我们写我们的ShowAllAdminServlet用于展示所有用户,同样的我们重写get和post方法,让post调用get
在get里就无需收参了,我们通过业务层拿到admins列表,然后在一个table里遍历admins打印数据,写上注释,路径为showall
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.hjj.servletProject.servlet; import com.hjj.servletProject.entity.Admin; import com.hjj.servletProject.service.AdminService; import com.hjj.servletProject.service.impl.AdminServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PipedWriter; import java.io.PrintWriter; import java.util.List; /** * @author Layton * @version 1.0 * @date 2020/11/23 18:36 */ @WebServlet("/showall") public class ShowAllAdminServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("123321"); resp.setContentType("text/html;charset=utf-8"); AdminService adminService = new AdminServiceImpl(); List<Admin> admins = adminService.showAllAdmin(); PrintWriter pw = resp.getWriter(); if(admins != null){ pw.println("<html>"); pw.println("<head>"); pw.println("<meta charset='UTF-8'>"); pw.println("<title>显示所有</title>"); pw.println("</head>"); pw.println("<body>"); pw.println("<table>"); pw.println(" <tr>"); pw.println(" <td>username</td>"); pw.println(" <td>password</td>"); pw.println(" <td>phone</td>"); pw.println(" <td>address</td>"); pw.println(" </tr>"); for(Admin admin: admins){ pw.println(" <tr>"); pw.println(" <td>"+admin.getUsername()+"</td>"); pw.println(" <td>"+admin.getPassword()+"</td>"); pw.println(" <td>"+admin.getPhone()+"</td>"); pw.println(" <td>"+admin.getAddress()+"</td>"); pw.println(" </tr>"); } pw.println("</table>"); pw.println("</body>"); pw.println("</html>"); }else{ pw.println("<html>"); pw.println("<head>"); pw.println("<meta charset='UTF-8>"); pw.println("<title>显示所有<title>"); pw.println("</head>"); pw.println("<body>"); pw.println("<h3>当前没有用户<h3>"); pw.println("</body>"); pw.println("</html>"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
接着我们启动服务器,访问/showall,nice~