自定义异常和响应结果

整体结构:
common公共层

  • constants包
    -- ResultSetEnum 响应结果集枚举类

  • vo包
    -- ResultSet全局统一响应结果类

  • util包
    -- ExceptionUtil 打印异常堆栈信息类

  • handler包
    -- GlobalExceptionHandler 统一异常处理类

  • exception包
    -- GuLiException 自定义异常类


接下来直接上代码:
1. ResultSetEnum 响应结果集枚举类

import lombok.Getter;

@Getter
public enum ResultSetEnum {
    SUCCESS(true,20000,"成功"),
    UNKNOWN_REASON(false,20001,"未知错误"),
    BAD_SQL_GRAMMAR(false,21001,"sql语法错误"),
    JSON_PARSE_ERROR(false,21002,"json解析异常"),
    PARAM_ERROR(false,21003,"参数不正确"),
    FILE_UPLOAD_ERROR(false,21004,"文件上传错误"),
    EXCEL_DATA_IMPORT_ERROR(false,21005,"EXCEL数据导入错误");

    /** 响应是否成功 */
    private Boolean success;
    /** 返回码 */
    private Integer code;
    /** 返回消息 */
    private String message;

    ResultSetEnum(Boolean success, Integer code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;
    }
}

2. ResultSet全局统一响应结果类

import com.common.constants.ResultSetEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;
@Data  // import lombok.Data;GetSet注解
@ApiModel(value = "全局统一返回结果")
public class ResultSet {
    @ApiModelProperty(value = "是否成功")
    private Boolean success;
    @ApiModelProperty(value = "返回码")
    private Integer code;
    @ApiModelProperty(value = "返回消息")
    private String message;
    @ApiModelProperty(value = "返回数据")
    private Map<String,Object> data = new HashMap<String, Object>();

    /** 私有构造方法,使外界无法new */
    private ResultSet(){}

    /** 响应成功静态方法 */
    public static ResultSet ok(){  // 公开静态方法,实例一个创建好的对象提供给外界
        ResultSet resultSet = new ResultSet();
        resultSet.setSuccess(ResultSetEnum.SUCCESS.getSuccess());
        resultSet.setCode(ResultSetEnum.SUCCESS.getCode());
        resultSet.setMessage(ResultSetEnum.SUCCESS.getMessage());
        return resultSet;
    }

    /** 响应失败静态方法 */
    public static ResultSet error(){
        ResultSet resultSet = new ResultSet();
        resultSet.setSuccess(ResultSetEnum.UNKNOWN_REASON.getSuccess());
        resultSet.setCode(ResultSetEnum.UNKNOWN_REASON.getCode());
        resultSet.setMessage(ResultSetEnum.UNKNOWN_REASON.getMessage());
        return resultSet;
    }

    /** 返回数据集合 */
    public ResultSet data(Map<String,Object> map){
        this.setData(map);
        return this;
    }

    /** 返回数据集合 */
    public ResultSet data(String key,Object value){
        this.data.put(key,value);
        return this;
    }

    /** 自定义信息 */
    public ResultSet message(String message){
        this.setMessage(message);
        return this;
    }
    /** 自定义错误码 */
    public ResultSet code(Integer code){
        this.setCode(code);
        return this;
    }

    /** 自定义是否成功 */
    public ResultSet success(Boolean success){
        this.setSuccess(success);
        return this;
    }

    /** 枚举值赋值给结果集 */
    public static ResultSet setResult(ResultSetEnum resultSetEnum){
        ResultSet resultSet = new ResultSet();
        resultSet.setSuccess(resultSetEnum.getSuccess());
        resultSet.setCode(resultSetEnum.getCode());
        resultSet.setMessage(resultSetEnum.getMessage());

        return resultSet;
    }
}

3. ExceptionUtil 打印异常堆栈信息工具类

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class ExceptionUtil {

    public static String getMessage(Exception e){
        StringWriter sw = null;
        PrintWriter pw = null;

        try{
            sw = new StringWriter();
            pw = new PrintWriter(sw);

            // 将出错误的信息输出到printWriter
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        }finally {
            if (sw != null){
                try {
                    sw.close();
                }catch (IOException e1){
                    e1.printStackTrace();
                }
            }
            if (pw != null){
               pw.close();
            }
        }
        return sw.toString();
    }
}

4. GlobalExceptionHandler 统一异常处理类

import com.common.constants.ResultSetEnum;
import com.common.exception.GuLiException;
import com.common.util.ExceptionUtil;
import com.common.vo.ResultSet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /** 未知异常 */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResultSet error(Exception e){
//        e.printStackTrace();    // 输出异常堆栈信息
        log.error(e.getMessage());
        return ResultSet.error();
    }

    /** sql语法异常 */
    @ExceptionHandler(BadSqlGrammarException.class)
    @ResponseBody
    public ResultSet error(BadSqlGrammarException e){
//        e.printStackTrace();    // 输出异常堆栈信息
        log.error(e.getMessage());
        return ResultSet.setResult(ResultSetEnum.BAD_SQL_GRAMMAR);
    }

    /** json解析异常 */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public ResultSet error(HttpMessageNotReadableException e){
//        e.printStackTrace();    // 输出异常堆栈信息
        log.error(e.getMessage());
        return ResultSet.setResult(ResultSetEnum.JSON_PARSE_ERROR);
    }

    /** 自定义异常 */
    @ExceptionHandler(GuLiException.class)
    @ResponseBody
    public ResultSet error(GuLiException e){
//        e.printStackTrace();    // 输出异常堆栈信息
        log.error(ExceptionUtil.getMessage(e));
        return ResultSet.error().message(e.getMessage()).code(e.getCode());
    }
}

5. GuLiException 自定义异常类

import com.common.constants.ResultSetEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "自定义全局异常类")
public class GuLiException extends RuntimeException{

    @ApiModelProperty(value = "状态码")
    private Integer code;

    /**
     * 接收状态码和错误消息
     * @param code
     * @param message
     */
    public GuLiException(Integer code,String message){
        super(message);
        this.code = code;
    }

    public GuLiException(ResultSetEnum resultSetEnum){
        super(resultSetEnum.getMessage());
        this.code = resultSetEnum.getCode();
    }

    @Override
    public String toString() {
        return "GuLiException{" +
                "code=" + code +
                ",message=" + this.getMessage() +
                '}';
    }
}

写一个service接口

import com.edu.entity.Subject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.edu.vo.SubjectNestedVo;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public interface SubjectService extends IService<Subject> {
    List<String> batchImport(MultipartFile file) throws Exception;  //lst集合封装错误数据
    List<SubjectNestedVo> nestedList();
}

实现类

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.common.util.ExcelImportUtil;
import com.edu.entity.Subject;
import com.edu.mapper.SubjectMapper;
import com.edu.service.SubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.vo.SubjectNestedVo;
import com.edu.vo.SubjectVo;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {

    @Override
    public List<String> batchImport(MultipartFile file) throws Exception{
       // 错误消息
        List<String> errorMsg = new ArrayList<>();

        // 创建工具类对象
        ExcelImportUtil excelHSSFUtil = new ExcelImportUtil(file.getInputStream());

        // 获取工作表
        Sheet sheet = excelHSSFUtil.getSheet();

        int rowCount = sheet.getPhysicalNumberOfRows();
        if (rowCount <= 1){
            errorMsg.add("请填写数据");
            return errorMsg;
        }

        for (int rowNum = 1; rowNum < rowCount; rowNum++) {
            Row rowData = sheet.getRow(rowNum);
            if (rowData != null){

                // 获取一级分类
                String levelOneValue = "";
                Cell levelOneCell = rowData.getCell(0);
                if (levelOneCell != null){
                    levelOneValue = excelHSSFUtil.getCellValue(levelOneCell).trim();
                    if (StringUtils.isEmpty(levelOneValue)){
                        errorMsg.add("第" + (rowNum + 1) + "行一级分类为空");
                        continue;
                    }
                }

                // 判断一级分类是否重复
                Subject subject = this.getByTitle(levelOneValue);
                String parentId = null;
                if (subject == null){   // 如果为null,将一级分类存入数据库
                    Subject subjectLevelOne = new Subject();
                    subjectLevelOne.setTitle(levelOneValue);
                    subjectLevelOne.setSort(rowNum);
                    baseMapper.insert(subjectLevelOne); // 向数据库插入数据

                    parentId = subjectLevelOne.getId(); // 父id为二级分类做准备
                }else { // 不为null则代表重复。只取父id
                    parentId = subject.getId();
                }

                // 获取二级分类
                String levelTwoValue = "";
                Cell levelTwoCell = rowData.getCell(1);
                if (levelTwoCell != null){
                    levelTwoValue = excelHSSFUtil.getCellValue(levelTwoCell).trim();
                    if (StringUtils.isEmpty(levelTwoValue)){
                        errorMsg.add("第" + (rowNum + 1) + "行二级分类为空");
                        continue;
                    }
                }
                // 判断二级分类是否重复
                Subject subject2 = this.getByTitle(levelTwoValue, parentId);
                Subject subjectLevelTwo = null;
                if (subject2 == null){  // 如果为null,将二级分类存入数据库
                    subjectLevelTwo = new Subject();
                    subjectLevelTwo.setTitle(levelTwoValue);
                    subjectLevelTwo.setParentId(parentId);
                    subjectLevelTwo.setSort(rowNum);
                    baseMapper.insert(subjectLevelTwo); // 向数据库插入数据
                }
            }
        }

        return errorMsg;
    }

 @Override
    public List<SubjectNestedVo> nestedList() {
        //最终要的到的数据列表
        ArrayList<SubjectNestedVo> subjectNestedVoArrayList = new ArrayList<>();

        //获取一级分类数据记录
        QueryWrapper<Subject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", 0);
        queryWrapper.orderByAsc("sort", "id");
        List<Subject> subjects = baseMapper.selectList(queryWrapper);

        //获取二级分类数据记录
        QueryWrapper<Subject> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.ne("parent_id", 0);
        queryWrapper2.orderByAsc("sort", "id");
        List<Subject> subSubjects = baseMapper.selectList(queryWrapper2);

        //填充一级分类vo数据
        int count = subjects.size();
        for (int i = 0; i < count; i++) {
            Subject subject = subjects.get(i);

            //创建一级类别vo对象
            SubjectNestedVo subjectNestedVo = new SubjectNestedVo();
            BeanUtils.copyProperties(subject, subjectNestedVo);
            subjectNestedVoArrayList.add(subjectNestedVo);

            //填充二级分类vo数据
            ArrayList<SubjectVo> subjectVoArrayList = new ArrayList<>();
            int count2 = subSubjects.size();
            for (int j = 0; j < count2; j++) {

                Subject subSubject = subSubjects.get(j);
                if(subject.getId().equals(subSubject.getParentId())){

                    //创建二级类别vo对象
                    SubjectVo subjectVo = new SubjectVo();
                    BeanUtils.copyProperties(subSubject, subjectVo);
                    subjectVoArrayList.add(subjectVo);
                }
            }

            subjectNestedVo.setChildren(subjectVoArrayList);
        }

        return subjectNestedVoArrayList;
    }

    /** 根据分类名称查询这个一级分类是否存在 */
    private Subject getByTitle(String title){

        QueryWrapper<Subject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title",title); // 查课程名称是否相同
        queryWrapper.eq("parent_id","0"); // 一级分类是否为0
        return baseMapper.selectOne(queryWrapper);
    }

    /** 根据分类名称和父类id查询这个二级分类中是否存在 */
    private Subject getByTitle(String title,String parentId){
        QueryWrapper<Subject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title",title); // 查课程名称是否相同
        queryWrapper.eq("parent_id",parentId); // 当前父id和表中父类id是否相同
        return baseMapper.selectOne(queryWrapper);
    }
}

controller方法

@RestController
@RequestMapping("/admin/edu/subject")
@CrossOrigin  //跨域
@Api(description = "课程科目管理")
@Slf4j
public class SubjectAdminController {

    @Autowired
    private SubjectService subjectService;

    /** excel导入科目 */
    @ApiOperation(value = "excel导入科目")
    @PostMapping("/import")
    public ResultSet batchImport(
            @ApiParam(name = "file",value = "excel文件",required = true)
            @RequestParam("file") MultipartFile file){
        try {
            List<String> errorMsg = subjectService.batchImport(file);

            if (errorMsg.size() == 0){
                return ResultSet.ok().message("批量数据导入成功");
            }else {
                return ResultSet.error().message("部分数据导入失败").data("errorMsgList",errorMsg);
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new GuLiException(ResultSetEnum.EXCEL_DATA_IMPORT_ERROR);
        }
    }


    /** 获取分类列表 */
    @ApiOperation(value = "嵌套数据列表")
    @GetMapping("")
    public ResultSet nestedList(){

        List<SubjectNestedVo> subjectNestedVoList = subjectService.nestedList();
        return ResultSet.ok().data("items", subjectNestedVoList);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容