controller.java.ftl 模板文件参考示例2

以下是修改后的 controller.java.ftl 模板文件,使用自定义的 ApiResponse 统一响应类,并将 @Autowired 改为 @Resource 注解:

package ${package.Controller};

<#-- 导入必要的类 -->
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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.tags.Tag;
import org.springframework.web.bind.annotation.*;

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * ${table.comment!} 控制器
 * </p>
 *
 * <p>
 * 本控制器提供对 ${table.comment!} 实体的 RESTful API 接口,遵循 OpenAPI 3.0 规范,
 * 使用 SpringDoc(Swagger 3)注解进行 API 文档描述,并返回统一的 ApiResponse 格式。
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Tag(name = "${table.comment!} 管理", description = "提供 ${table.comment!} 相关的增删改查接口")
@RestController
@RequestMapping("/${table.mappingPath}")
public class ${table.controllerName} {

    @Resource
    private ${table.serviceName} ${table.serviceName?uncap_first};

    /**
     * 根据 ID 查询 ${table.comment!}
     *
     * @param id 主键 ID
     * @return 统一响应格式,包含查询结果,若存在则返回 200 状态码,否则返回 404 状态码
     */
    @Operation(
        summary = "根据ID获取${table.comment!}",
        description = "通过主键ID查询单个${table.comment!}记录",
        responses = {
            @ApiResponse(
                responseCode = "200",
                description = "查询成功",
                content = @Content(mediaType = "application/json", schema = @Schema(implementation = ApiResponse.class))
            ),
            @ApiResponse(responseCode = "404", description = "未找到对应记录")
        }
    )
    @GetMapping("/{id}")
    public ApiResponse<${entity}> getById(
        @Parameter(description = "主键ID", required = true, example = "1")
        @PathVariable("id") Long id) {
        ${entity} entity = ${table.serviceName?uncap_first}.getById(id);
        if (entity != null) {
            return ApiResponse.success(entity);
        } else {
            return ApiResponse.fail("未找到ID为 " + id + " 的记录");
        }
    }

    /**
     * 查询所有 ${table.comment!} 列表
     *
     * @return 统一响应格式,包含所有 ${table.comment!} 的列表
     */
    @Operation(
        summary = "获取所有${table.comment!}列表",
        description = "返回数据库中所有${table.comment!}记录",
        responses = {
            @ApiResponse(
                responseCode = "200",
                description = "查询成功",
                content = @Content(mediaType = "application/json", schema = @Schema(implementation = ApiResponse.class))
            )
        }
    )
    @GetMapping
    public ApiResponse<List<${entity}>> listAll() {
        List<${entity}> list = ${table.serviceName?uncap_first}.list();
        return ApiResponse.success(list);
    }

    /**
     * 新增 ${table.comment!}
     *
     * @param ${entity?uncap_first} 待保存的 ${table.comment!} 对象
     * @return 统一响应格式,包含保存成功后的实体(含自增ID等)
     */
    @Operation(
        summary = "新增${table.comment!}",
        description = "创建一个新的${table.comment!}记录",
        requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
            description = "需要创建的${table.comment!}对象",
            required = true,
            content = @Content(mediaType = "application/json", schema = @Schema(implementation = ${entity}.class))
        ),
        responses = {
            @ApiResponse(
                responseCode = "200",
                description = "创建成功",
                content = @Content(mediaType = "application/json", schema = @Schema(implementation = ApiResponse.class))
            ),
            @ApiResponse(responseCode = "400", description = "请求参数错误")
        }
    )
    @PostMapping
    public ApiResponse<${entity}> save(
        @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "待新增的实体", required = true)
        @RequestBody ${entity} ${entity?uncap_first}) {
        boolean success = ${table.serviceName?uncap_first}.save(${entity?uncap_first});
        if (success) {
            return ApiResponse.success(${entity?uncap_first}, "新增成功");
        } else {
            return ApiResponse.fail("新增失败");
        }
    }

    /**
     * 更新 ${table.comment!}
     *
     * @param ${entity?uncap_first} 更新后的 ${table.comment!} 对象(需包含有效ID)
     * @return 统一响应格式,返回更新是否成功
     */
    @Operation(
        summary = "更新${table.comment!}",
        description = "根据ID更新已存在的${table.comment!}记录",
        requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
            description = "更新后的${table.comment!}对象,必须包含ID",
            required = true,
            content = @Content(mediaType = "application/json", schema = @Schema(implementation = ${entity}.class))
        ),
        responses = {
            @ApiResponse(responseCode = "200", description = "更新成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误或ID不存在")
        }
    )
    @PutMapping
    public ApiResponse<Boolean> update(
        @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "待更新的实体", required = true)
        @RequestBody ${entity} ${entity?uncap_first}) {
        boolean success = ${table.serviceName?uncap_first}.updateById(${entity?uncap_first});
        if (success) {
            return ApiResponse.success(success, "更新成功");
        } else {
            return ApiResponse.fail("更新失败,可能ID不存在");
        }
    }

    /**
     * 根据 ID 删除 ${table.comment!}
     *
     * @param id 要删除的记录 ID
     * @return 统一响应格式,返回删除是否成功
     */
    @Operation(
        summary = "根据ID删除${table.comment!}",
        description = "逻辑删除或物理删除指定ID的${table.comment!}记录(取决于服务层实现)",
        parameters = {
            @Parameter(name = "id", description = "要删除的记录ID", required = true, example = "1")
        },
        responses = {
            @ApiResponse(responseCode = "200", description = "删除成功"),
            @ApiResponse(responseCode = "404", description = "ID不存在")
        }
    )
    @DeleteMapping("/{id}")
    public ApiResponse<Boolean> deleteById(
        @Parameter(description = "要删除的记录ID", required = true, example = "1")
        @PathVariable("id") Long id) {
        boolean success = ${table.serviceName?uncap_first}.removeById(id);
        if (success) {
            return ApiResponse.success(success, "删除成功");
        } else {
            return ApiResponse.fail("删除失败,ID为 " + id + " 的记录不存在");
        }
    }
}

🔧 配套的统一响应类 ApiResponse.java

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;

import lombok.Data;

/**
 * 统一响应结果封装类
 * 
 * @param <T> 响应数据类型
 */
@Data
@Schema(description = "统一响应结果")
public class ApiResponse<T> {

    @Schema(description = "响应状态码", example = "200")
    private int code;

    @Schema(description = "响应消息", example = "操作成功")
    private String message;

    @Schema(description = "响应数据")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T data;

    public ApiResponse() {}

    public ApiResponse(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 成功响应
     */
    public static <T> ApiResponse<T> success() {
        return new ApiResponse<>(200, "操作成功", null);
    }

    public static <T> ApiResponse<T> success(String message) {
        return new ApiResponse<>(200, message, null);
    }

    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(200, "操作成功", data);
    }

    public static <T> ApiResponse<T> success(T data, String message) {
        return new ApiResponse<>(200, message, data);
    }

    /**
     * 失败响应
     */
    public static <T> ApiResponse<T> fail() {
        return new ApiResponse<>(500, "操作失败", null);
    }

    public static <T> ApiResponse<T> fail(String message) {
        return new ApiResponse<>(500, message, null);
    }

    public static <T> ApiResponse<T> fail(Integer code, String message) {
        return new ApiResponse<>(code, message, null);
    }
}

📝 修改说明:

  1. 统一响应格式

    • 使用自定义的 ApiResponse<T> 作为返回类型
    • 包含 code(状态码)、message(消息)、data(数据)三个字段
    • 使用 @JsonInclude(JsonInclude.Include.NON_NULL) 避免空数据字段的序列化
  2. 注解变更

    • @Autowired 改为 @Resource(JSR-250 标准注解,按名称注入)
    • @Resource 默认按名称注入,更精确,推荐使用
  3. 返回值调整

    • 所有方法返回 ApiResponse<T> 格式
    • 使用 ApiResponse.success()ApiResponse.fail() 静态方法构建响应
  4. OpenAPI 注解

    • @Schema(implementation = ApiResponse.class) 指定响应体结构
    • API 文档中会正确显示统一响应格式
  5. 业务逻辑增强

    • 根据操作结果返回不同的消息和状态码
    • 更好的错误处理和用户提示

这个模板符合企业级开发规范,提供了完整的统一响应处理方案。

Exception in thread "main" java.lang.RuntimeException: 无法创建文件,请检查配置信息! at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.batchOutput(AbstractTemplateEngine.java:256) at com.baomidou.mybatisplus.generator.AutoGenerator.execute(AutoGenerator.java:179) at com.baomidou.mybatisplus.generator.FastAutoGenerator.execute(FastAutoGenerator.java:229) at com.example.micromall.Generator.CodeGenerator.main(CodeGenerator.java:161) Caused by: java.lang.RuntimeException: freemarker.template.TemplateNotFoundException: Template not found for name "/templates/myEntity.java.ftl". The name was interpreted by this TemplateLoader: ClassTemplateLoader(resourceLoaderClass=com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine, basePackagePath="/"). at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.outputFile(AbstractTemplateEngine.java:197) at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.lambda$outputEntity$2(AbstractTemplateEngine.java:96) at java.base/java.util.Optional.ifPresent(Optional.java:178) at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.outputEntity(AbstractTemplateEngine.java:94) at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.lambda$batchOutput$9(AbstractTemplateEngine.java:247) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine.batchOutput(AbstractTemplateEngine.java:238) ... 3 more Caused by: freemarker.template.TemplateNotFoundException: Template not found for name "/templates/myEntity.java.ftl". The name was interpreted by this TemplateLoader: ClassTemplateLoader(resourceLoaderClass=com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine, basePackagePath="/"). at freemarker.template.Configuration.getTemplate(Configuration.java:2957) at freemarker.template.Configuration.getTemplate(Configuration.java:2759) at com.baomidou.mybatisplus.generator.engine.FreemarkerTempla
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙茶清欢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值