ToB企服应用市场:ToB评测及商务社交产业平台

标题: 搭建一个JavaWeb项目流程详解 [打印本页]

作者: 魏晓东    时间: 2024-4-11 00:40
标题: 搭建一个JavaWeb项目流程详解
搭建一个JavaWeb项目流程

本文致力于,让编程者一步步明白书写一个JavaWeb项目应该做些什么,梳理清楚流程框架,需要的jar包,同时手写了一个分页工具类也在其中,让你在编程中更加丝滑。
1.src\main\java\com\einmeer\qianyu

删除系统默认生成的HelloServlet.java
1.1tools包

DruidTools.java
需要在lib中加入druid-1.1.22.jar
  1. package com.einmeer.qianyu.tools;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import com.alibaba.druid.pool.DruidDataSourceFactory;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.sql.Connection;
  7. import java.sql.SQLException;
  8. import java.util.Properties;
  9. /**
  10. * @author 芊嵛
  11. * @date 2024/1/18
  12. * JDBC操作,就是在java中操作数据库
  13. * 封装数据库连接工具,带连接池的
  14. */
  15. public class DruidTools {
  16.     //声明连接池对象
  17.     private  static DruidDataSource dataSource;
  18.     //java的静态代码块,作初始化用
  19.     static {
  20.         //读取外部配置文件的内容,生成字节流输入流对象
  21.         InputStream in = DruidTools.class.getResourceAsStream("/Druid.properties");
  22.         //创建属性集合对象
  23.         Properties properties = new Properties();
  24.         try {
  25.             //加载输入流对象
  26.             properties.load(in);
  27.             //生成连接池对象
  28.             dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
  29.         } catch (IOException e) {
  30.             e.printStackTrace();
  31.         } catch (Exception e) {
  32.             e.printStackTrace();
  33.         }
  34.     }
  35.     //获取接池对象,便于dbutils使用,简化原生JDBC的增删改查功能CURD
  36.     public static DruidDataSource getDataSource(){
  37.         return  dataSource;
  38.     }
  39.     //拿到数据库连接对象,便于我们操作MYSQL
  40.     public static Connection getConn() {//方便之后重复使用
  41.         Connection conn = null;
  42.         try {
  43.             //创建数据库连接对象(数据库地址,用户名,密码)
  44.             conn = dataSource.getConnection();
  45.             System.out.println("数据库连接成功success!");
  46.         } catch (SQLException e) {
  47.             e.printStackTrace();
  48.         }
  49.         return conn;
  50.     }
  51.     ////测试一下,建议用单元测试
  52.     public static void main(String[] args) {
  53.         getConn();
  54.     }
  55. }
复制代码
Pagination.java
分页,封装好了方法之后直接调用就行
  1. package com.einmeer.qianyu.tools;
  2. import java.util.List;
  3. /**
  4. * @author 芊嵛
  5. * @date 2024/1/19
  6. */
  7. public class Pagination<T> { // 使用泛型是为了复用
  8.     // 当前页号
  9.     private int currentPage;
  10.     // 总页号或总页数
  11.     private int totalPage;
  12.     // 每页记录数或行数
  13.     private int limitRows;
  14.     // 总的记录数或行数
  15.     private int totalRows;
  16.     // 每页开始的记录号
  17.     private int startRecord;
  18.     // 每页结束的记录号,这个没用,只需每页记录行数limitRows即可
  19.     // private int endRecord;
  20.     // 存每页中的记录
  21.     private List<T> list;
  22.     // //初始化操作
  23.     public void init() {
  24.         // 1.求总页数,通过总记录数与每页行数来计算,有几种情况
  25.         // (1)不够一页(2)有零头(3)刚好是整数页
  26.         int tp = totalRows / limitRows;
  27.         if (totalRows > limitRows) {
  28.             // 判断是是刚刚好还是一页多一点
  29.             totalPage = (totalRows % limitRows) == 0 ? tp : tp + 1;
  30.         } else {
  31.             totalPage = 1;
  32.         }
  33.         // 2.将当页保留在第一页或最后一页
  34.         if (currentPage > totalPage) {
  35.             currentPage = totalPage;
  36.         } else if (currentPage < 1) {
  37.             currentPage = 1;
  38.         }
  39.         // 3.初始化开始记录数,mysql应用的limit它不包括开始记录,所以不要加1;
  40.         // 还有limit传入的是开始记录号与查询的条数,此处是每页可显示数limitRows,
  41.         // 如果查到最后没有limitRows限制的行数,则显示剩余部分
  42.         this.startRecord = (currentPage - 1) * limitRows;
  43.     }
  44.     // 无参构造,便于使用
  45.     public Pagination() {
  46.     }
  47.     // 当前页号,总记录数,每页行数;这些属性需要传入后初始化,其它的可以set设置
  48.     public Pagination(int currentPage, int totalRows, int limitRows) {
  49.         this.currentPage = currentPage;
  50.         this.totalRows = totalRows;
  51.         this.limitRows = limitRows;
  52.     }
  53.     // get与set方法
  54.     public int getCurrentPage() {
  55.         return currentPage;
  56.     }
  57.     public void setCurrentPage(int currentPage) {
  58.         this.currentPage = currentPage;
  59.     }
  60.     public int getTotalPage() {
  61.         return totalPage;
  62.     }
  63.     public void setTotalPage(int totalPage) {
  64.         this.totalPage = totalPage;
  65.     }
  66.     public int getLimitRows() {
  67.         return limitRows;
  68.     }
  69.     public void setLimitRows(int limitRows) {
  70.         this.limitRows = limitRows;
  71.     }
  72.     public int getTotalRows() {
  73.         return totalRows;
  74.     }
  75.     public void setTotalRows(int totalRows) {
  76.         this.totalRows = totalRows;
  77.     }
  78.     public int getStartRecord() {
  79.         return startRecord;
  80.     }
  81.     public void setStartRecord(int startRecord) {
  82.         this.startRecord = startRecord;
  83.     }
  84.     public List<T> getList() {
  85.         return list;
  86.     }
  87.     public void setList(List<T> list) {
  88.         this.list = list;
  89.     }
  90. }
复制代码
1.2entity包

Entity层,实体层,放入实体类
详解Lombok中的@Builder用法
  1. // Lombok注解
  2. @Builder        // 一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程,不写@Builder,@AllArgsConstructor会报红
  3. @Data        // 提供了get、set、equals、toString方法
  4. @NoArgsConstructor        // 生成一个无产构造函数
  5. @AllArgsConstructor // 生成一个包含所有变量的有参构造函数
复制代码
实现序列化
Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。
参考java实体类为什么要实现Serializable接口
  1. implements Serializable
复制代码
1.3dao包

DAO数据访问层,把访问数据库的代码封装起来,不涉及业务逻辑
  1. // 接口:写需要的细分功能的名字,能用sql语句表示出来,如格局用户id查询用户全部信息
  2. User selectUserById(Long userId);
复制代码
  1. // 实现类
  2. //1.建议先定义一个全局结果集返回对象,应为每次运行sql语句都会返回结果
  3. QueryRunner qr = new QueryRunner(DruidTools.getDataSource());
  4. // 2.每个接口第一句都把返回值类型置为空(查询语句置为null)或者0(增删改置为0)
  5. List<User> list = null;
  6. int n = 0;
  7. // 3.每个接口第二句写sql语句(我这里举例简单写写*号实际一定不要写*)
  8. String sql = "select * from user where username like ? and userGender = ? limit ?,?";
  9. // 4.创建一个对象类数组(里面放?号代替的东西,注意位置不要错)
  10. // 如果就一个参数或者不需要参数不用写这个,多个参数再写
  11. Object[] param = {"%"+username+"%",userGender,start,number};
  12. // 5.处理异常,执行sql
  13. try {
  14.     // 查询
  15.     // 返回list结果集BeanListHandler<>()
  16.     // 返回对象BeanHandler<>()
  17.     // 返回单个数据ScalarHandler<>()
  18.     // query(String sql, ResultSetHandler<T> rsh)
  19.     // query(String sql, Object param, ResultSetHandler<T> rsh)
  20.     // query(String sql, Object[] params, ResultSetHandler<T> rsh)
  21.     // 更多可以看看源码
  22.     list = qr.query(sql, new BeanListHandler<User>(User.class));
  23.     user = qr.query(sql, param, new BeanHandler<>(User.class));
  24.     // 这个看其他资料说是返回Object类型需要转,但是我测试并不需要,返回的就是我要的类型
  25.     n = qr.query(sql,parm,new ScalarHandler<>());
  26.    
  27.     // 更新/删除/插入
  28.     // update(String sql, Object param)
  29.     // update(String sql, Object... params)
  30.     n = qr.update(sql, username);
  31.     n = qr.update(sql, param);
  32. } catch (SQLException e) {
  33.     throw new RuntimeException(e);
  34. }
  35. // 6.return 第一步的名字;
  36. return list;
  37. return n;
复制代码
1.4service包

Service业务逻辑层,处理逻辑上的业务,而不去考虑具体的实现。
通过调用数据访问层,实现逻辑上的业务,一个接口的实现可能需要多个dao层的接口
  1. // 接口:定义好方法,之后servlet直接调用,与servlet方法数量相同
  2. // 名字最好不要跟dao层一样
  3. // dao:select
  4. // service:query
复制代码
  1. // 实现类
  2. // 1.全局调一下dao层,方便下面调用
  3. private UserDao userDao = new UserDaoImpl;
  4. // 2.自由发挥
复制代码
1.5servlet包

Servlet(Server Applet)是Java Servlet的简称,是为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容。
  1. // 1.注解,
  2. @WebServlet("/user")
  3. // 2.继承HttpServlet
  4. public class UserServlet extends HttpServlet{}
  5. // 3.创建服务类对象
  6. private UserService userService = new UserServiceImpl();
  7. // 4.重写doGet()方法,如果调用它就会调用doPost()方法
  8. @Override
  9. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  10.     doPost(req, resp);
  11. }
  12. // 5.重写doPost()方法
  13. @Override
  14. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  15.     // 首局一定要写这句,把用户传来的数据如果有汉字转为汉字,不然乱码
  16.     req.setCharacterEncoding("utf8");
  17.     // 这里我前端页面隐藏了一个表单,区分页面传入的是哪个方法
  18.     // <input type="hidden" name="method" value="pn-prid">
  19.     String method = req.getParameter("method");
  20.     // 根据method判断需要调用什么方法
  21. }
  22. // 6.具体方法,举一个例子
  23. public void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  24.     // 前端传来的参数
  25.     String proCode = req.getParameter("queryProCode");
  26.     String proName = req.getParameter("queryProName");
  27.     Object current = req.getParameter("current");
  28.     // 实现分页(当时划分不清楚,这块感觉可以写进service进行封装)
  29.     int temp1 = 0;
  30.     if (current != null) {
  31.         temp1 = Integer.parseInt(req.getParameter("current"));
  32.     }
  33.     long temp = ps.queryCount(proCode,proName);
  34.     int totalRows = (int) temp;
  35.     Pagination<Provider> pg = new Pagination<>(temp1, totalRows, 10);
  36.     pg.init();
  37.     List<Provider> providers = ps.queryLimit(proCode,proName,pg.getStartRecord(), 10);
  38.     pg.setList(providers);
  39.         // 携带数据请求转发
  40.     RequestDispatcher rd = req.getRequestDispatcher("WEB-INF/jsp/providerlist.jsp");
  41.     // 携带数据
  42.     req.setAttribute("p1",proCode);
  43.     req.setAttribute("p2",proName);
  44.     req.setAttribute("providers", pg.getList());
  45.     req.setAttribute("pg", pg);
  46.     rd.forward(req, resp);
  47. }
复制代码
2.src\main\resources

druid.properties
  1. # 如果mysql是5版本的去掉cj
  2. driverClassName=com.mysql.cj.jdbc.Driver
  3. # 端口号默认3306如果修改了记得把此处进行修改
  4. # 记得修改数据库的名字
  5. url=jdbc:mysql://localhost:3306/数据库名字?rewriteBatchedStatements=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
  6. # 数据库账号,根据实际填写
  7. username=root
  8. # 数据库密码,根据实际填写
  9. password=quanyu9988.gmail.com
  10. # 一般不需要更改,初始化数据库连接池
  11. initialSize=10
  12. # 一般不需要更改,连接池的最大数据库连接数
  13. maxActive=20
  14. # 一般不需要更改,超时等待时间一毫秒为单位
  15. maxWait=1000
  16. # 一般不需要更改,连接池的最小空闲连接数,如果空闲的连接数大于该值,则关闭多余连接,反之创建更多连接满足最小连接数的要求
  17. minIdle=5
复制代码
3.src\main\webapp

3.1WEB-INF\lib


  1. // 不导入,连接池用不了
  2. druid-1.1.22.jar
  3. // 导入可以使用QueryRunner类+ResultSetHandler类,更方便的完成curd
  4. commons-dbutils-1.7.jar
  5. // 数据库驱动,我这里用的8
  6. mysql-connector-java-8.0.25.jar
  7. //使用JSTL核心标签库,需要导入下面两个依赖
  8. standard.jar
  9. jstl.jar
复制代码
3.2WEB-INF\jsp

存放无法直接在地址栏访问的界面
3.3WEB-INF\web.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5.          version="4.0">
  6.    
  7.     <welcome-file-list>
  8.         <welcome-file>login.jsp</welcome-file>
  9.     </welcome-file-list>
  10. </web-app>
复制代码
3.4暴露在外面的内容

例如:
css
js
images
以及能直接在地址栏访问的界面
login.jsp
register.jsp
下面jsp页面第八行必须写上,才能证明他是jsp页面
  1. <%--
  2.     Created by IntelliJ IDEA.
  3.     User: Qy
  4.         Date: 2024/1/18
  5.             Time: 20:42
  6.                 To change this template use File | Settings | File Templates.
  7.                 --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  9. <%--如果用到了核心标签记得加上核心标签库--%>
  10. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  11. <html>
  12.     <head>
  13.         <title>Title</title>
  14.         <%--所有外面的静态资源一定要用<%=request.getContextPath()%>代替..不然找不到数据--%>
  15.         <link type="text/css" rel="stylesheet" href="<%=request.getContextPath()%>/css/style.css"/>
  16.     </head>
  17.     <body>
  18.     </body>
  19. </html>
复制代码
4.pom.xml

这份说明没用到maven,采取自己导入jar包,这么的代码没有修改只是作为说明
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.    
  6.     <modelVersion>4.0.0</modelVersion>
  7.    
  8.    
  9.     <groupId>com.einmeer</groupId>
  10.    
  11.     <artifactId>qianyu</artifactId>
  12.    
  13.     <version>1.0-SNAPSHOT</version>
  14.    
  15.     <name>qianyu</name>
  16.    
  17.     <packaging>war</packaging>
  18.    
  19.     <properties>
  20.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  21.         <maven.compiler.target>1.8</maven.compiler.target>
  22.         <maven.compiler.source>1.8</maven.compiler.source>
  23.         <junit.version>5.9.2</junit.version>
  24.     </properties>
  25.    
  26.     <dependencies>
  27.         
  28.         <dependency>
  29.             <groupId>org.projectlombok</groupId>
  30.             <artifactId>lombok</artifactId>
  31.             <version>1.18.24</version>
  32.             <scope>provided</scope>
  33.         </dependency>
  34.         <dependency>
  35.             
  36.             <groupId>javax.servlet</groupId>
  37.             
  38.             <artifactId>javax.servlet-api</artifactId>
  39.             
  40.             <version>4.0.1</version>
  41.             
  42.             <scope>provided</scope>
  43.         </dependency>
  44.         <dependency>
  45.             <groupId>org.junit.jupiter</groupId>
  46.             <artifactId>junit-jupiter-api</artifactId>
  47.             <version>${junit.version}</version>
  48.             <scope>test</scope>
  49.         </dependency>
  50.         <dependency>
  51.             <groupId>org.junit.jupiter</groupId>
  52.             <artifactId>junit-jupiter-engine</artifactId>
  53.             <version>${junit.version}</version>
  54.             <scope>test</scope>
  55.         </dependency>
  56.     </dependencies>
  57.    
  58.     <build>
  59.         <plugins>
  60.             <plugin>
  61.                 <groupId>org.apache.maven.plugins</groupId>
  62.                 <artifactId>maven-war-plugin</artifactId>
  63.                 <version>3.3.2</version>
  64.             </plugin>
  65.         </plugins>
  66.     </build>
  67. </project>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4