二、后端基本框架搭建

15 阅读5分钟

后端基本框架搭建

一般搭建一个后端服务流程,先规划目录。JavaWeb最通用的就是MVC架构,controlle,service,dao,entity。然后就是一些常量目录、配置文件目录等。本篇主要完成目标:

  1. 搭建好整体目录

  2. 添加一些常量类、工具类、常用对象(响应结果、分页等),以及根据数据表添加实体类,创建枚举类。

  3. 创建一个接口,并成功调用

  4. 最终目标 image-20251224151341192.png

1、后端目录

personal-plan-server
├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─dong
│  │  │          └─plan
│  │  │              ├─config
│  │  │              ├─constant
│  │  │              ├─enums
│  │  │              ├─model
│  │  │              ├─service
│  │  │              ├─util
│  │  │              └─web
│  │  │                  ├─controller
│  │  │                  ├─entity
│  │  │                  ├─model
│  │  │                  ├─repository
│  │  │                  └─service

2、配置文件

  1. redis配置文件,主要用来解决存储的数据可视化时乱码

    package com.dong.plan.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    /**
     * Redis配置类
     *
     * @author LD 2025-11-25 11:22:34
     */
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(redisConnectionFactory);
    
            // 使用StringRedisSerializer来序列化和反序列化redis的key值
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new StringRedisSerializer());
    
            // 使用GenericJackson2JsonRedisSerializer来序列化和反序列化redis的value值
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
    
            template.afterPropertiesSet();
            return template;
        }
    }
    
    

3、常量类

常量类主要用来规范一些魔法值,复用一些通用值等等

  1. 通用常量

    package com.dong.plan.constant;
    
    /**
     * @author LD 2021/5/28
     */
    public class CommonConstant {
    
        private CommonConstant() {
        }
    
        /**
         * 是
         */
        public static final int YES = 1;
    
        /**
         * 否
         */
        public static final int NO = 0;
    
    }
    
    
  2. 响应码常量

    package com.dong.plan.constant;
    
    /**
     * 响应码常量
     */
    public class ResponseCodeConstant {
    
        public static final Integer SUCCESS_CODE = 200;//成功响应码
        public static final Integer FAILURE_CODE = 500;//失败响应码
    }
    
    
  3. 响应消息常量

    package com.dong.plan.constant;
    
    /**
     * 响应消息常量
     */
    public class ResponseMessageConstant {
    
        public static final String LOGIN_SUCCESS = "登录成功";
        public static final String LOGOUT_SUCCESS = "退出登录成功";
        public static final String REGISTER_SUCCESS = "注册成功";
        public static final String UPLOAD_SUCCESS = "上传成功";
        public static final String OPERATE_SUCCESS = "操作成功";
        public static final String SAVE_SUCCESS = "保存成功";
        public static final String DELETE_SUCCESS = "删除成功";
        public static final String QUERY_SUCCESS = "查询成功";
        public static final String UPLOAD_ERROR = "上传失败";
        public static final String OPERATE_ERROR = "操作失败";
        public static final String SAVE_ERROR = "保存失败";
        public static final String DELETE_ERROR = "删除失败";
        public static final String QUERY_ERROR = "查询失败";
    }
    
    
  4. 符号常量

    package com.dong.plan.constant;
    
    /**
     * 符号常量
     *
     * @author LD
     */
    public class SymbolConstant {
    
        /**
         * 点
         */
        public static final String DOT = ".";
    
        /**
         * 斜杠
         */
        public static final String SLASH = "/";
    
        /**
         * 反斜杠
         */
        public static final String BACKSLASH = "\";
    
        /**
         * 下划线
         */
        public static final String UNDERLINE = "_";
    
        /**
         * 连字符
         */
        public static final String HYPHEN = "-";
    
        /**
         * 冒号
         */
        public static final String COLON = ":";
    
        /**
         * 星号
         */
        public static final String ASTERISK = "*";
    
        /**
         * 百分号
         */
        public static final String PERCENT = "%";
    
        /**
         * 问号
         */
        public static final String QUESTION_MARK = "?";
    
        /**
         * 逗号
         */
        public static final String COMMA = ",";
    }
    
    

4、工具类

后续工具类基本会选择使用hutool工具,但是也想说明, 一般企业都会有一套自己的代码框架,会有自己的工具类,常量类。

package com.dong.plan.util;

import java.util.UUID;

/**
 * 公共工具类
 *
 * @author LD
 */
public class CommonUtils {

    /**
     * 获取32位无字母与数字组合的uuid
     *
     * @return
     */
    public static String getUUID() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString().replaceAll("-", "");
    }

}

5、模型类

  1. 分页结果

    package com.dong.plan.model;
    
    import org.springframework.data.domain.Page;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 分页结果
     *
     * @author LD
     */
    public class PageVO<T> {
    
        /**
         * 当前页码
         */
        private int currentPage = 1;
    
        /**
         * 记录总数
         */
        private int total = 0;
    
        /**
         * 页码总数
         */
        private int pageTotal = 0;
    
        /**
         * 分页数据
         */
        private List<T> dataList = new ArrayList<>();
    
        public PageVO(int currentPage, int total, List<T> dataList) {
            this.currentPage = currentPage;
            this.total = total;
            this.pageTotal = (int) Math.ceil((double) total / 10);
            this.dataList = dataList;
        }
    
        public PageVO(int currentPage, int total, int pageTotal, List<T> dataList) {
            this.currentPage = currentPage;
            this.total = total;
            this.pageTotal = pageTotal;
            this.dataList = dataList;
        }
    
        public PageVO() {
    
        }
    
        public int getCurrentPage() {
            return currentPage;
        }
    
        public void setCurrentPage(int currentPage) {
            if (currentPage <= 0) {
                this.currentPage = 1;
            } else {
                this.currentPage = currentPage;
            }
        }
    
        public int getTotal() {
            return total;
        }
    
        public void setTotal(int total) {
            this.total = total;
            this.pageTotal = (int) Math.ceil((double) total / 10);
        }
    
        public int getPageTotal() {
            return pageTotal;
        }
    
        public void setPageTotal(int pageTotal) {
            this.pageTotal = pageTotal;
        }
    
        public List<T> getDataList() {
            return dataList;
        }
    
        public void setDataList(List<T> dataList) {
            this.dataList = dataList;
        }
    
    
        /**
         * 根据 org.springframework.data.domain.Page 转换为 pagination
         *
         * @param page
         * @param <T>
         * @param <E>
         * @return 返回PageVO<T>
         */
        public static <T, E> PageVO<T> convertPager(Page<E> page, List<T> dtoList) {
            PageVO<T> pagination = new PageVO<>();
            pagination.setCurrentPage(page.getNumber());
            pagination.setTotal((int) page.getTotalElements());
            pagination.setPageTotal(page.getTotalPages());
            pagination.setDataList(dtoList);
            return pagination;
        }
    }
    
  2. 分页对象

    package com.dong.plan.model;
    
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    
    /**
     * 分页
     *
     * @author LD
     */
    public class Pagination {
    
        /**
         * 当前页码
         */
        private int page = 1;
        /**
         * 每页数量
         */
        private int limit = 10;
    
        public int getPage() {
            return page;
        }
    
        public void setPage(int page) {
            this.page = page;
        }
    
        public int getLimit() {
            return limit;
        }
    
        public void setLimit(int limit) {
            this.limit = limit;
        }
    
        public Integer getOffset() {
            return (this.page - 1) * limit;
        }
    
        /**
         * 根据pager转换为org.springframework.data.domain.Pageable
         *
         * @return org.springframework.data.domain.Pageable
         */
        public Pageable toPageable() {
            return PageRequest.of(this.page, this.limit);
        }
    
        /**
         * 根据pager转换为org.springframework.data.domain.Pageable
         *
         * @param sort
         * @return org.springframework.data.domain.Pageable
         */
        public Pageable toPageable(Sort sort) {
            return PageRequest.of(this.page - 1, this.limit, sort);
        }
    
    }
    
  3. 响应结果

    package com.dong.plan.model;
    
    /**
     * 响应结果
     *
     * @author LD
     * @date 2020/3/22 21:57
     */
    public class ResponseResult<T> {
    
        private int code = 200;
        private String message;
        private T data;
    
        /**
         * 操作成功
         *
         * @param data
         * @param message
         * @return
         */
        public static <T> ResponseResult<T> success(T data, String message) {
            ResponseResult<T> result = new ResponseResult<>();
            result.setCode(200);
            result.setData(data);
            result.setMessage(message);
            return result;
        }
    
        /**
         * 操作成功
         *
         * @param message
         * @return
         */
        public static <T> ResponseResult<T> success(String message) {
            ResponseResult<T> result = new ResponseResult<>();
            result.setCode(200);
            result.setMessage(message);
            return result;
        }
    
        /**
         * 操作失败
         *
         * @param message
         * @return
         */
        public static <T> ResponseResult<T> error(String message) {
            ResponseResult<T> result = new ResponseResult<>();
            result.setCode(500);
            result.setMessage(message);
            return result;
        }
    
        /**
         * 操作失败
         *
         * @param message
         * @return
         */
        public static <T> ResponseResult<T> error(Integer code, String message) {
            ResponseResult<T> result = new ResponseResult<>();
            result.setCode(code);
            result.setMessage(message);
            return result;
        }
    
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
    }
    

6、第一个接口

package com.dong.plan.web.controller;

import com.dong.plan.constant.ResponseMessageConstant;
import com.dong.plan.model.ResponseResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 仪表盘
 *
 * @author LD 2025-12-02 15:32:19
 */
@RestController
@RequestMapping("/dashboard")
public class DashboardController {

    /**
     * 生成每日激励语
     *
     * @return
     */
    @GetMapping("/generateDailyMotivation")
    public ResponseResult<String> generateDailyMotivation() {
        String result = "清醒时做事,迷茫时读书,独处时思考,焦虑时运动。";
        return ResponseResult.success(result, ResponseMessageConstant.QUERY_SUCCESS);
    }
}

后续

  • 这篇主要是搭一个基本框架,不涉及业务开发
  • 以上面的目录与代码基本可以作为一个模板用于其他项目
  • 等项目积累多了,可以添加更多高频使用工具类、常量类、配置文件、以及抽象类、接口等等
  • 下篇将写前端基本架构搭建,调用写好的第一个接口
  • 之后前后端结合一起写,尽量保证每个版本都是一个可用的产品
  • 欢迎各位指正