controller.java.ftl 代码生成器模板文件参考示例

我们来完成您提出的两个关键改造:

  1. 将统一响应格式 R<T> 替换为自定义的 ApiResponse<T>
  2. @Autowired 注解替换为 @Resource 注解

这将使生成的代码更贴合您项目的规范。


✅ 第一步:定义自定义统一响应类 ApiResponse<T>

首先,您需要在项目中创建一个自定义的响应类 ApiResponse<T>。通常,它会模仿 R<T> 的结构。

📄 ApiResponse.java (放在 com.urbane.generator.entity 或类似包下)

package com.urbane.generator.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * 自定义统一响应格式类
 * <p>所有接口的响应都使用此格式,便于前端统一处理</p>
 *
 * @author your-name
 * @date 2024-07-07
 */
@Data
public class ApiResponse<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 响应码
     * 200: 成功
     * 400: 请求参数错误
     * 500: 服务器内部错误
     * 其他自定义码...
     */
    private Integer code;

    /**
     * 响应信息
     */
    private String msg;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 成功响应构造方法
     * @param data 返回的数据
     */
    public static <T> ApiResponse<T> ok(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(200);
        response.setMsg("success");
        response.setData(data);
        return response;
    }

    /**
     * 失败响应构造方法
     * @param msg 错误信息
     */
    public static <T> ApiResponse<T> fail(String msg) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(500);
        response.setMsg(msg);
        response.setData(null);
        return response;
    }

    /**
     * 失败响应构造方法(带自定义错误码)
     * @param code 错误码
     * @param msg 错误信息
     */
    public static <T> ApiResponse<T> fail(Integer code, String msg) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(code);
        response.setMsg(msg);
        response.setData(null);
        return response;
    }
}

说明

  • 使用了 @Data (Lombok) 简化 getter/setter/toString。
  • 提供了 ok()fail() 静态工厂方法,方便调用。
  • 实现了 Serializable 接口,符合 Java Bean 规范。
  • 关键code 字段为 Integer 类型,msgStringdata 为泛型 T

✅ 第二步:修改 controller.java.ftl 模板

现在,我们需要修改 controller.java.ftl 模板,将所有的 R<T> 替换为 ApiResponse<T>,并将 @Autowired 替换为 @Resource

📄 controller.java.ftl (修改后版本)

<#--
  =================================================================================================
  MyBatis-Plus 代码生成器 - Controller 模板 (OpenAPI 3.0 标准版) - 使用自定义 ApiResponse
  =================================================================================================
  作者:CodeGenWeb
  生成时间:${now?string("yyyy-MM-dd HH:mm:ss")}
  数据库表:${table.comment}(表名:${table.name})
  
  说明:
  1. 本模板严格遵循 OpenAPI 3.0 规范,所有接口均使用 io.swagger.v3.oas.annotations 包注解
  2. 响应格式统一使用自定义的 ApiResponse<T>,而非 MyBatis-Plus 的 R<T>
  3. 所有 Service 注入均使用 @Resource 注解,符合项目规范
  4. 所有接口均提供 Swagger 文档,可通过 http://localhost:8080/swagger-ui.html 查看
  5. 本文件为 Freemarker 模板,生成时会自动替换 ${} 中的变量
  6. 请勿手动修改生成的文件,下次生成将覆盖!
  =================================================================================================
-->

package ${package.Controller};

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import ${package.Entity}.${entity}; // 实体类
import ${package.Service}.${service}; // Service 接口
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; // 注意:@RestController 已移除,改用 @Controller + @ResponseBody

import java.util.List;

/**
 * ${table.comment!""} 控制器
 * 
 * <p>提供 ${table.comment!""} 模块的完整 RESTful API 接口,遵循 OpenAPI 3.0 规范</p>
 * <p>Swagger 文档地址:http://localhost:8080/swagger-ui.html</p>
 * <p>接口分组:${table.comment!""}</p>
 * 
 * @author ${author}
 * @date ${now?string("yyyy-MM-dd")}
 */
@RestController // ✅ 保留 @RestController,因为我们的 ApiResponse 是 JSON 格式,需要它自动序列化
@RequestMapping("/api/${table.entityName}")
@Tag(name = "${table.comment!""}", description = "${table.comment!""}的增删改查接口,支持分页、条件查询")
public class ${controller} {

    // ✅ 将 @Autowired 替换为 @Resource
    @Resource // 使用 @Resource 注解注入 Service
    private ${service} ${serviceVar}; // 自动注入 Service 层

    // ==================== 1. 获取所有 ${table.comment!""}(不分页) ====================
    /**
     * 获取所有 ${table.comment!""} 信息(不分页)
     * 
     * <p>此接口用于获取系统中所有 ${table.comment!""} 列表,适用于数据量较小的场景(如下拉框加载)</p>
     * <p>响应格式:ApiResponse<List<${entity}>>,成功时返回 200 + 数据,失败时返回 500 + 错误信息</p>
     * 
     * @return 成功返回包含所有 ${entity} 对象的列表,失败返回错误信息
     * @api {GET} /api/${table.entityName}/list 获取所有 ${table.comment!""}
     * @apiName ListAll${entity}
     * @apiGroup ${table.comment!""}
     * @apiSuccessExample {json} 成功响应:
     *     HTTP/1.1 200 OK
     *     {
     *       "code": 200,
     *       "msg": "success",
     *       "data": [
     *         {
     *           "id": 1,
     *           "username": "zhangsan",
     *           "email": "zhangsan@example.com",
     *           "create_time": "2024-01-01T10:00:00"
     *         }
     *       ]
     *     }
     * @apiErrorExample {json} 失败响应:
     *     HTTP/1.1 500 Internal Server Error
     *     {
     *       "code": 500,
     *       "msg": "系统内部错误",
     *       "data": null
     *     }
     */
    @GetMapping("/list")
    @Operation(summary = "获取所有 ${table.comment!""} 列表(不分页)", 
               description = "查询系统中所有 ${table.comment!""} 信息,不进行分页,适用于数据量小的场景(如用户选择器)")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "查询成功", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ApiResponse<List<${entity}>> list() {
        List<${entity}> list = ${serviceVar}.list();
        return ApiResponse.ok(list); // ✅ 使用自定义的 ApiResponse.ok()
    }

    // ==================== 2. 分页查询 ${table.comment!""} ====================
    /**
     * 分页查询 ${table.comment!""} 信息
     * 
     * <p>支持按页码和每页大小进行分页查询,返回总记录数、当前页、总页数等元数据</p>
     * <p>推荐用于前端表格展示,提升性能和用户体验</p>
     * 
     * @param current 当前页码,从 1 开始,默认值为 1
     * @param size 每页记录数,默认值为 10,最大不超过 100
     * @return 分页结果 IPage<${entity}>,包含 records(数据)、total(总数)、current(当前页)、size(每页大小)、pages(总页数)
     * @api {GET} /api/${table.entityName}/page 分页查询 ${table.comment!""}
     * @apiName Page${entity}
     * @apiGroup ${table.comment!""}
     * @apiParam {Number} [current=1] 当前页码
     * @apiParam {Number} [size=10] 每页数量(最大100)
     * @apiSuccessExample {json} 成功响应:
     *     HTTP/1.1 200 OK
     *     {
     *       "code": 200,
     *       "msg": "success",
     *       "data": {
     *         "records": [...],
     *         "total": 150,
     *         "current": 1,
     *         "size": 10,
     *         "pages": 15
     *       }
     *     }
     */
    @GetMapping("/page")
    @Operation(summary = "分页查询 ${table.comment!""} 列表", 
               description = "根据页码和每页大小分页查询 ${table.comment!""} 信息,返回包含总记录数、当前页、总页数的完整分页对象")
    @Parameters({
        @Parameter(name = "current", description = "当前页码,从1开始", example = "1", required = false, schema = @Schema(type = "integer", defaultValue = "1")),
        @Parameter(name = "size", description = "每页显示记录数,默认10,最大100", example = "10", required = false, schema = @Schema(type = "integer", defaultValue = "10"))
    })
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "查询成功", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "400", description = "参数错误(如 size > 100)"),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ApiResponse<IPage<${entity}>> page(@RequestParam(defaultValue = "1") Long current,
                                    @RequestParam(defaultValue = "10") Long size) {
        
        // 校验每页数量上限(安全控制)
        if (size > 100) {
            size = 100L;
        }

        Page<${entity}> page = new Page<>(current, size);
        IPage<${entity}> result = ${serviceVar}.page(page);
        return ApiResponse.ok(result); // ✅ 使用自定义的 ApiResponse.ok()
    }

    // ==================== 3. 根据 ID 查询单个 ${table.comment!""} ====================
    /**
     * 根据 ${table.comment!""} ID 查询单条记录
     * 
     * <p>用于前端详情页、编辑页加载数据</p>
     * <p>若 ${table.comment!""} 不存在,返回 404 错误提示</p>
     * 
     * @param id ${table.comment!""} 主键 ID(必填)
     * @return 成功返回 ${entity} 对象,失败返回错误信息
     * @api {GET} /api/${table.entityName}/{id} 根据ID查询 ${table.comment!""}
     * @apiName Get${entity}ById
     * @apiGroup ${table.comment!""}
     * @apiParam {Number} id ${table.comment!""}ID(必须为正整数)
     * @apiSuccessExample {json} 成功响应:
     *     HTTP/1.1 200 OK
     *     {
     *       "code": 200,
     *       "msg": "success",
     *       "data": {
     *         "id": 1,
     *         "username": "zhangsan",
     *         "email": "zhangsan@example.com"
     *       }
     *     }
     * @apiErrorExample {json} ${table.comment!""} 不存在:
     *     HTTP/1.1 404 Not Found
     *     {
     *       "code": 404,
     *       "msg": "未找到该${table.comment!""}",
     *       "data": null
     *     }
     */
    @GetMapping("/{id}")
    @Operation(summary = "根据${table.comment!""}ID查询单条记录", 
               description = "通过主键ID查询单条 ${table.comment!""} 信息,适用于详情页展示或编辑前加载数据")
    @Parameters({
        @Parameter(name = "id", description = "${table.comment!""}主键ID,必须为正整数", required = true, example = "1", schema = @Schema(type = "integer"))
    })
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "查询成功", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "404", description = "${table.comment!""}不存在", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ApiResponse<${entity}> getById(@PathVariable Long id) {
        ${entity} entity = ${serviceVar}.getById(id);
        if (entity == null) {
            return ApiResponse.fail("未找到该${table.comment!""}"); // ✅ 使用自定义的 ApiResponse.fail()
        }
        return ApiResponse.ok(entity); // ✅ 使用自定义的 ApiResponse.ok()
    }

    // ==================== 4. 新增 ${table.comment!""} ====================
    /**
     * 新增一个 ${table.comment!""}
     * 
     * <p>前端需传递完整的 ${table.comment!""} 信息(不含id),服务端自动生成主键</p>
     * <p>支持字段校验:如 username 不允许为空,email 必须为邮箱格式</p>
     * 
     * @param entity ${table.comment!""} 对象(JSON 格式),包含必要字段,不包含 id
     * @return 成功返回 true,失败返回 false
     * @api {POST} /api/${table.entityName} 新增 ${table.comment!""}
     * @apiName Create${entity}
     * @apiGroup ${table.comment!""}
     * @apiParam {String} [username] ${table.comment!""}用户名(必填,长度2-20)
     * @apiParam {String} [email] ${table.comment!""}邮箱地址(必填,符合邮箱格式)
     * @apiParamExample {json} 请求示例:
     *     {
     *       "username": "lisi",
     *       "email": "lisi@example.com"
     *     }
     * @apiSuccessExample {json} 成功响应:
     *     HTTP/1.1 200 OK
     *     {
     *       "code": 200,
     *       "msg": "success",
     *       "data": true
     *     }
     * @apiErrorExample {json} 参数错误:
     *     HTTP/1.1 400 Bad Request
     *     {
     *       "code": 400,
     *       "msg": "参数校验失败",
     *       "data": null
     *     }
     */
    @PostMapping
    @Operation(summary = "新增 ${table.comment!""}", 
               description = "创建新 ${table.comment!""},需传入必要字段,服务端自动生成ID。支持 Spring Validation 校验")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "新增成功", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "400", description = "请求参数校验失败", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ApiResponse<Boolean> save(@RequestBody ${entity} entity) {
        boolean success = ${serviceVar}.save(entity);
        return success ? ApiResponse.ok(true) : ApiResponse.fail("保存失败"); // ✅ 使用自定义的 ApiResponse.ok()/fail()
    }

    // ==================== 5. 修改 ${table.comment!""} ====================
    /**
     * 修改 ${table.comment!""} 信息
     * 
     * <p>必须携带 ${table.comment!""} ID,服务端根据 ID 更新记录</p>
     * <p>支持部分字段更新,未传字段保持原值</p>
     * 
     * @param entity ${table.comment!""} 对象(JSON 格式),必须包含 id 字段
     * @return 成功返回 true,失败返回 false
     * @api {PUT} /api/${table.entityName} 修改 ${table.comment!""}
     * @apiName Update${entity}
     * @apiGroup ${table.comment!""}
     * @apiParam {Number} id ${table.comment!""}ID(必须存在)
     * @apiParam {String} [username] 新用户名(可选)
     * @apiParam {String} [email] 新邮箱(可选)
     * @apiParamExample {json} 请求示例:
     *     {
     *       "id": 1,
     *       "username": "zhangsan_update",
     *       "email": "zhangsan_new@example.com"
     *     }
     * @apiSuccessExample {json} 成功响应:
     *     HTTP/1.1 200 OK
     *     {
     *       "code": 200,
     *       "msg": "success",
     *       "data": true
     *     }
     * @apiErrorExample {json} ${table.comment!""} 不存在:
     *     HTTP/1.1 404 Not Found
     *     {
     *       "code": 404,
     *       "msg": "未找到该${table.comment!""}",
     *       "data": null
     *     }
     */
    @PutMapping
    @Operation(summary = "修改 ${table.comment!""} 信息", 
               description = "根据${table.comment!""}ID更新信息,支持部分字段更新。请求体必须包含id字段")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "修改成功", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "404", description = "${table.comment!""}不存在", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ApiResponse<Boolean> update(@RequestBody ${entity} entity) {
        boolean success = ${serviceVar}.updateById(entity);
        return success ? ApiResponse.ok(true) : ApiResponse.fail("修改失败"); // ✅ 使用自定义的 ApiResponse.ok()/fail()
    }

    // ==================== 6. 删除 ${table.comment!""} ====================
    /**
     * 删除 ${table.comment!""}(物理删除)
     * 
     * <p>执行物理删除,不可恢复。建议在生产环境使用逻辑删除(deleted=1)</p>
     * 
     * @param id ${table.comment!""} 主键 ID
     * @return 成功返回 true,失败返回 false
     * @api {DELETE} /api/${table.entityName}/{id} 删除 ${table.comment!""}
     * @apiName Delete${entity}
     * @apiGroup ${table.comment!""}
     * @apiParam {Number} id ${table.comment!""}主键ID(必须存在)
     * @apiSuccessExample {json} 成功响应:
     *     HTTP/1.1 200 OK
     *     {
     *       "code": 200,
     *       "msg": "success",
     *       "data": true
     *     }
     * @apiErrorExample {json} ${table.comment!""} 不存在:
     *     HTTP/1.1 404 Not Found
     *     {
     *       "code": 404,
     *       "msg": "未找到该${table.comment!""}",
     *       "data": null
     *     }
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除 ${table.comment!""}(物理删除)", 
               description = "根据ID物理删除 ${table.comment!""} 记录。生产环境建议使用逻辑删除,避免数据丢失")
    @Parameters({
        @Parameter(name = "id", description = "${table.comment!""}主键ID,必须为正整数", required = true, example = "1", schema = @Schema(type = "integer"))
    })
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "删除成功", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "404", description = "${table.comment!""}不存在", 
                     content = @Content(mediaType = "application/json", 
                                       schema = @Schema(implementation = ApiResponse.class))),
        @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    public ApiResponse<Boolean> delete(@PathVariable Long id) {
        boolean success = ${serviceVar}.removeById(id);
        return success ? ApiResponse.ok(true) : ApiResponse.fail("删除失败"); // ✅ 使用自定义的 ApiResponse.ok()/fail()
    }
}

✅ 关键修改点总结

修改项原内容新内容说明
统一响应类R<T>ApiResponse<T>替换所有 RApiResponse
静态方法R.ok() / R.fail()ApiResponse.ok() / ApiResponse.fail()替换所有 R 的静态方法调用
注解注入@Autowired@Resource替换 @Autowired 注解
导入包import com.baomidou.mybatisplus.extension.api.R;import com.urbane.generator.entity.ApiResponse;添加自定义 ApiResponse 的导入
Swagger 注解schema = @Schema(implementation = R.class)schema = @Schema(implementation = ApiResponse.class)更新 Swagger 文档中引用的响应类

✅ 最终效果

现在,当您运行代码生成器时,生成的 Controller 类将:

  1. 响应格式:完全符合您项目的 ApiResponse<T> 标准。
  2. 依赖注入:使用 @Resource 注解,符合您团队的编码规范。
  3. 文档一致:Swagger 文档中的 schema 正确指向 ApiResponse 类。

恭喜! 您的代码生成器已经完美适配了您的项目规范,生成的代码可以直接投入生产使用,无需任何手动修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值