@RequestMapping("/api/file/tactics") //以api开头,controller具体功能
public class FileTacticsController {
@PostMapping("/page") //方法具体作用
public ReturnT page(@RequestBody FileTacticsQueryVo vo) {
}
@GetMapping("/get/{id}") //restful风格
public ReturnT getById(@PathVariable(name = "id") Integer id) {
return fileTacticsService.getVoById(id);
}
@RestController
@RequestMapping("/api/migrateLog")
@Api(tags = "审计管理-迁移日志") //指明所处模块
public class JobLogController extends BaseController {
@Autowired
private SysConfigService sysConfigService;
@Resource
private JobLogService jobLogService;
//接口所具有的作用,以及请求方式
@ApiOperation(value = "运行日志列表", notes = "运行日志列表", httpMethod = "POST")
@PostMapping("/logPageList")
@OperateLog(module = "审计管理-迁移日志", type = "运行日志列表", des = "运行日志列表")
public ReturnT<Map<String, Object>> pageList(@RequestBody MigrateLogVo migrateLogVo) {
return jobLogService.logPageList(migrateLogVo);
}
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ReturnT exceptionHandler(){
//具体处理逻辑...
}
@ExceptionHandler(BusinessException.class)
public ReturnT businessExceptionHandler(){
//具体处理逻辑...
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ReturnT methodArgumentNotValidExceptionHandler(){
//具体处理逻辑...
}
}
@Override
public void add(JobUserVo vo) {
//...
JobUser existUser = jobUserMapper.selectOne(new QueryWrapper<>(whereUser));
if (existUser != null) {
throw new BusinessException(I18nUtil.getString("user_username_repeat"));
}
//...
}
logger.error(e.getMessage());
logger.error("程序发生异常,异常原因{}",e.getMessage())
public ReturnT xxx(){
try{
xxxService.xxx();
}catch(Exception e){
return ReturnT.failed(e.getMessage());
}
}
try{
}catch(xxxException e){
logger.error(e.getMessage(),e);
}
@Override
public void downloadFileJobTargetFile(int id, HttpServletResponse response) throws IOException {
JobMigrateInfo jobMigrateInfo = jobMigrateInfoMapper.selectById(id);
if (jobMigrateInfo.getMigrateType() != CommonConstant.FILE_TO_FILE_TACTICS && jobMigrateInfo.getMigrateType() != CommonConstant.DATA_TO_FILE_TACTICS)
throw new FileDownLoadException("任务目的源不是文件,无法提供目标文件下载"); //以此种方式抛出异常,全局异常统一处理,修改Http状态码。
if (jobMigrateInfo.getRunState() != JobMigrateInfo.FINISH_RUN) {
throw new FileDownLoadException("当前任务未完成执行,无法下载迁移目标文件");
}
JobTactics jobTactics = jobTacticsMapper.selectById(jobMigrateInfo.getTacticsId());
FileWriterConfig fileWriterConfig = fileWriterConfigMapper.selectById(jobTactics.getWriteConfigId());
FileTypeEnum fileTypeEnum = FileTypeEnum.convertByTypeCode(fileWriterConfig.getFileType());
File targetFile = new File(fileWriterConfig.getPath() + fileWriterConfig.getFileName() + "." + fileTypeEnum.getExt());
if (!targetFile.exists()) {
throw new FileDownLoadException("下载文件失败,未找到目标文件");
}
ServletUtils.setDownloadFileResponseHeader(response, fileWriterConfig.getFileName() + "." + fileTypeEnum.getExt());
ServletOutputStream outputStream = response.getOutputStream();
FileInputStream fileInputStream = new FileInputStream(targetFile);
IoUtil.copy(fileInputStream, outputStream);
IoUtil.close(fileInputStream);
IoUtil.close(outputStream);
}
@Override
public IPage<JobUserLog> getPage(JobUserLogVo log) {
IPage<JobUserLog> page = new Page<>(log.getCurrent(), log.getSize());
QueryWrapper<JobUserLog> wrapper = new QueryWrapper<>();
return this.baseMapper.selectPage(page, wrapper);
}
vo
@ApiModel("操作日志接收对象")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class JobUserLogVo extends JobUserLog {
@ApiModelProperty(value = "当前页")
private int current;
@ApiModelProperty(value = "每页大小")
private int size;
}
spring:
profiles:
active: dev
@ApiModel(value = "JobMigrateAddVo")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JobMigrateAddVo {
@ApiModelProperty(value = "id")
private int id;
@ApiModelProperty(value = "任务名")
private String name;
@ApiModelProperty(value = "申请者id")
private int applyId;
@ApiModelProperty(value = "策略id")
private int tacticsId;
@ApiModelProperty(value = "任务执行周期,cron表达式")
private String jobCron;
public boolean formatAndVerify() {
this.jobCron = "* * * * * ? *";
return StringUtils.isNotBlank(name)
&& applyId > 0
&& tacticsId > 0
&& CronExpression.isValidExpression(jobCron);
}
}
@ApiModel("业务应用更新")
public class ReqUpdate {
/**
* 业务域ID
*/
@ApiModelProperty(value = "业务域ID", required = false)
@JsonProperty
@Pattern(regexp = ValidateUtils.REGEX_NO_HTML_TAG,message = "业务域ID存在非法字符!")
@Size(max = 32,message = "业务域ID长度超过最大32位")
private String businessDomainId;
/**
* 业务应用名称
*/
@ApiModelProperty(value = "业务应用名称", required = false)
@JsonProperty
@Pattern(regexp = ValidateUtils.REGEX_NO_HTML_TAG,message = "业务应用名称存在非法字符!")
@Size(max = 100,message = "业务应用名称长度超过最大100位")
private String name;
/**
* 部署级别:1.一级部署 2.二级部署
*/
@ApiModelProperty(value = "部署级别:1.一级部署 2.二级部署", required = false)
@JsonProperty
@Pattern(regexp = "1|2|",message = "部署级别只能为1或者2")
private String deployLevel;
}
public class ReturnT<T> implements Serializable {
public static final long serialVersionUID = 42L;
//错误码
public static final int SUCCESS_CODE = 200;
public static final int FAIL_CODE = 500;
public static final int PARAM_ERR_CODE = 555;
public static final int REQ_METHOD_ERR_CODE = 556;
public static final int UNAUTHORIZED_CODE = 401;
public static final int FILE_DOWNLOAD_FAIL_CODE = 586;
public static final ReturnT<String> SUCCESS = new ReturnT<String>(SUCCESS_CODE, "执行成功");
public static final ReturnT<String> FAIL = new ReturnT<>(FAIL_CODE, "执行失败");
private int code;
private String msg;
private T content;
public ReturnT() {
}
public ReturnT(int code, String msg) {
this.code = code;
this.msg = msg;
}
public ReturnT(int code, String msg, T content) {
this.code = code;
this.msg = msg;
this.content = content;
}
public ReturnT(T content) {
this.code = SUCCESS_CODE;
this.content = content;
}
public static <T> ReturnT<T> fail(String msg) {
return new ReturnT<T>(FAIL_CODE, msg);
}
public static ReturnT<String> failCode(Integer code, String msg) {
return new ReturnT<String>(code, msg);
}
public static ReturnT<String> failException(Exception e) {
if (e instanceof BusinessException) {
BusinessException businessException = (BusinessException) e;
return ReturnT.failCode(businessException.getCode(), businessException.getMessage());
} else if (e instanceof AccessDeniedException) {
return ReturnT.failCode(-1, e.getMessage());
}
return new ReturnT<String>(FAIL_CODE, e.getMessage());
}
public static ReturnT<String> fail(BusinessErrCode errCode) {
return new ReturnT<String>(errCode.getCode(), errCode.getMsg());
}
public static <T> ReturnT<T> fail(String msg, T data) {
return new ReturnT<T>(FAIL_CODE, msg, data);
}
public static <T> ReturnT<T> failData(T data) {
return new ReturnT<T>(FAIL_CODE, SUCCESS.msg, data);
}
public static <T> ReturnT<T> succ(String msg) {
return new ReturnT<T>(SUCCESS_CODE, msg);
}
public static <T> ReturnT<T> succData(T data) {
return new ReturnT<T>(SUCCESS_CODE, SUCCESS.msg, data);
}
public static <T> ReturnT<T> succ(String msg, T data) {
return new ReturnT<T>(SUCCESS_CODE, msg, data);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getContent() {
return content;
}
public void setContent(T content) {
this.content = content;
}
@Override
public String toString() {
return "ReturnT [code=" + code + ", msg=" + msg + ", content=" + content + "]";
}
}
举例,假设我们写了一个判断arraylist是否为空的函数,一开始是这样的:
public static boolean isEmpty(ArrayList<?> list) {
return list == null || list.size() == 0;
}
当有其他类型的集合也需要该方法的时候,就显得很无力。可以改成最抽象的一层去实现,例如:
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.size() == 0;
}
改完后,所有实现了Collection都对象都可以用,适用范围变得更大。