All skills
alffei avatar

/springboot-init

@e682457
by Andrew Chenalffei/skill_share68 stars
17

Define development specifications for Spring Boot monolithic projects, supporting multiple technology stack configurations.

Use this Skill: https://skilld.dev/gh/alffei/skill_share/springboot-init

This session only. Nothing lands on disk.

referencescode-templates.md

≈3.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

配置文件

application.yml

server:
  port: 8080
  servlet:
    context-path: /api

spring:
  application:
    name: {project}
  profiles:
    active: dev
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/{project}?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: {password}

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      logic-delete-field: is_delete
      logic-delete-value: 1
      logic-not-delete-value: 0
      id-type: assign_id

springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs

common 包

BaseResponse.java

package com.{company}.{project}.common;

import com.{company}.{project}.exception.ErrorCode;
import lombok.Data;

import java.io.Serializable;

@Data
public class BaseResponse<T> implements Serializable {
    private int code;
    private T data;
    private String message;

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

    public BaseResponse(T data, int code) {
        this.data = data;
        this.code = code;
    }

    public BaseResponse(ErrorCode errorCode) {
        this(errorCode.getCode(), null, errorCode.getMessage());
    }
}

PageRequest.java

package com.{company}.{project}.common;

import lombok.Data;

@Data
public class PageRequest {
    private int current = 1;
    private int pageSize = 10;
    private String sortField;
    private String sortOrder = "descend";
}

DeleteRequest.java

package com.{company}.{project}.common;

import lombok.Data;

import java.io.Serializable;

@Data
public class DeleteRequest implements Serializable {
    private Long id;
    private static final long serialVersionUID = 1L;
}

controller 包

MainController.java

系统健康检查接口。

package com.{company}.{project}.controller;

import com.{company}.{project}.common.BaseResponse;
import com.{company}.{project}.utils.ResultUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "MainController", description = "系统接口")
@RestController
@RequestMapping("/")
public class MainController {

    /**
     * 健康检查
     *
     * @return
     */
    @GetMapping("/health")
    @Operation(summary = "健康检查")
    public BaseResponse<String> health() {
        return ResultUtils.success("ok");
    }

    /**
     * 初始化检查(用于集成验证)
     */
    @GetMapping("/init-check")
    @Operation(summary = "初始化检查")
    public BaseResponse<String> initCheck() {
        return ResultUtils.success("SpringBoot Project Initialized Successfully!");
    }
}

exception 包

ErrorCode.java

package com.{company}.{project}.exception;

import lombok.Getter;

@Getter
public enum ErrorCode {
    SUCCESS(0, "ok"),
    PARAMS_ERROR(40000, "请求参数错误"),
    NOT_LOGIN_ERROR(40100, "未登录"),
    NO_AUTH_ERROR(40101, "无权限"),
    NOT_FOUND_ERROR(40400, "请求数据不存在"),
    FORBIDDEN_ERROR(40300, "禁止访问"),
    SYSTEM_ERROR(50000, "系统内部异常"),
    OPERATION_ERROR(50001, "操作失败");

    private final int code;
    private final String message;

    ErrorCode(int code, String message) {
        this.code = code;
        this.message = message;
    }
}

BusinessException.java

package com.{company}.{project}.exception;

import lombok.Getter;

@Getter
public class BusinessException extends RuntimeException {
    private final int code;

    public BusinessException(ErrorCode errorCode) {
        super(errorCode.getMessage());
        this.code = errorCode.getCode();
    }

    public BusinessException(int code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(ErrorCode errorCode, String message) {
        super(message);
        this.code = errorCode.getCode();
    }
}

GlobalExceptionHandler.java

package com.{company}.{project}.exception;

import com.{company}.{project}.common.BaseResponse;
import com.{company}.{project}.utils.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public BaseResponse<?> businessExceptionHandler(BusinessException e) {
        log.error("BusinessException", e);
        return ResultUtils.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {
        log.error("RuntimeException", e);
        return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误");
    }

    @ExceptionHandler(org.springframework.web.bind.MethodArgumentNotValidException.class)
    public BaseResponse<?> validationExceptionHandler(org.springframework.web.bind.MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        log.error("Validation Error: {}", message);
        return ResultUtils.error(ErrorCode.PARAMS_ERROR, message);
    }
}

utils 包

ResultUtils.java

package com.{company}.{project}.utils;

import com.{company}.{project}.common.BaseResponse;
import com.{company}.{project}.exception.ErrorCode;

public class ResultUtils {

    public static <T> BaseResponse<T> success(T data) {
        return new BaseResponse<>(0, data, "ok");
    }

    public static BaseResponse<?> error(ErrorCode errorCode) {
        return new BaseResponse<>(errorCode);
    }

    public static BaseResponse<?> error(int code, String message) {
        return new BaseResponse<>(code, null, message);
    }

    public static BaseResponse<?> error(ErrorCode errorCode, String message) {
        return new BaseResponse<>(errorCode.getCode(), null, message);
    }
}

ThrowUtils.java

package com.{company}.{project}.utils;

import com.{company}.{project}.exception.BusinessException;
import com.{company}.{project}.exception.ErrorCode;

public class ThrowUtils {

    public static void throwIf(boolean condition, RuntimeException e) {
        if (condition) {
            throw e;
        }
    }

    public static void throwIf(boolean condition, ErrorCode errorCode) {
        throwIf(condition, new BusinessException(errorCode));
    }

    public static void throwIf(boolean condition, ErrorCode errorCode, String message) {
        throwIf(condition, new BusinessException(errorCode, message));
    }
}

config 包

MybatisPlusConfig.java

MyBatis-Plus 分页插件配置,非 MyBatis-Plus 技术栈可跳过。

package com.{company}.{project}.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.{company}.{project}.mapper")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

JsonConfig.java

Long 类型序列化配置,解决前端 JS 精度丢失问题。

package com.{company}.{project}.config;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;

import java.io.IOException;

@JsonComponent
public class JsonConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            SimpleModule module = new SimpleModule();
            module.addSerializer(Long.class, ToStringSerializer.instance);
            module.addSerializer(Long.TYPE, ToStringSerializer.instance);
            module.addDeserializer(Long.class, new LongDeserializer());
            module.addDeserializer(Long.TYPE, new LongDeserializer());
            builder.modules(module);
        };
    }

    private static class LongDeserializer extends JsonDeserializer<Long> {
        @Override
        public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            if (p.currentToken() == JsonToken.VALUE_NUMBER_INT) {
                return p.getLongValue();
            }
            if (p.currentToken() == JsonToken.VALUE_STRING) {
                String value = p.getText().trim();
                if (value.isEmpty()) {
                    return null;
                }
                try {
                    return Long.parseLong(value);
                } catch (NumberFormatException e) {
                    throw new InvalidFormatException(p, "无效的Long格式", value, Long.class);
                }
            }
            throw ctxt.wrongTokenException(p, Long.class, JsonToken.VALUE_NUMBER_INT,
                    "Long类型仅支持数字或字符串格式");
        }
    }
}

OpenApiConfig.java

SpringDoc OpenAPI 配置。

package com.{company}.{project}.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenApiConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info().title("API 文档"));
    }
}

Source: SKILL.md on GitHub

No alerts7mo4 checks · Risk SAFE
  • Gen Agent Trust Hub7mo

    The skill 'springboot-init' defines architectural standards and templates for Spring Boot applications. It promotes best practices like DTO/VO separation and global exception handling. No malicious patterns or security risks were found.

  • Socket7mo

    No alerts

  • Snyk7mo

    Risk: LOW · No issues

  • Runlayer7mo

    2 files scanned · No issues

Signed by skilld at e682457. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for alffei/skill_share/springboot-init