1.阿里云OSS存储图片
- 1.创建bucket
-
2.创建Accesskey
创建完用户后,记得保存access-key和secret-key
添加oss权限和上传图片时允许跨域
-
3.Springcloud整合oss
本次使用服务端签名后直传,优点是安全性高不需要将AccessKey暴露在前端页面且效率高不需要服务端来处理上传OSS
https://help.aliyun.com/document_detail/31926.html
-
引入oss依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alicloud-oss</artifactId> </dependency>
-
配置yml
spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 heart-beat-interval: 1000 heart-beat-timeout: 3000 ip-delete-timeout: 6000 alicloud: # oss配置 access-key: secret-key: oss: endpoint: application: name: dreammall-third-party server: port: 30000
-
注意前端和后端返回的字段一定要一样 恶心到我了
-
成功效果
-
2.统一处理异常
package com.liubo.product.exception;
import com.liubo.common.enums.BizCodeEnume;
import com.liubo.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
/**
* 集中处理所有异常
*/
@Slf4j
@RestControllerAdvice(basePackages = "com.liubo.product.controller")
public class DreammallExceptionControllerAdvice {
@ExceptionHandler(value= MethodArgumentNotValidException.class)
public R handleVaildException(MethodArgumentNotValidException e){
log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String,String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError)->{
errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
});
return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable){
log.error("错误:",throwable);
return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
}
}
-
统一处理异常视觉效果
3.JSR303数据校验
-
do设置字段校验 (分组 更细粒度划分 添加校验还是修改校验)
public class Brand implements Serializable { /** * 品牌id */ @TableId(type = IdType.AUTO) @NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class}) @Null(message = "新增不能指定id",groups = {AddGroup.class}) private Long brandId; /** * 品牌名 */ @NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class}) private String name; /** * 品牌logo地址 */ @NotBlank(groups = {AddGroup.class}) @URL(message = "logo必须是一个合法的url地址",groups={AddGroup.class,UpdateGroup.class}) private String logo; /** * 介绍 */ private String descript; /** * 显示状态[0-不显示;1-显示] */ @NotNull(groups = {AddGroup.class, UpdateStatusGroup.class}) @ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class}) private Integer showStatus; /** * 检索首字母 */ @NotEmpty(groups={AddGroup.class}) @Pattern(regexp="^[a-zA-Z]$",message = "检索首字母必须是一个字母",groups={AddGroup.class,UpdateGroup.class}) private String firstLetter; /** * 排序 */ @NotNull(groups={AddGroup.class}) @Min(value = 0,message = "排序必须大于等于0",groups={AddGroup.class,UpdateGroup.class}) private Integer sort; @TableField(exist = false) private static final long serialVersionUID = 1L; }
-
controller 添加修改加上参数校验
-
举个例子 保存使用的分组**@Validated({AddGroup.class})**,那么do上面有groups={AddGroup.class}的字段就会进行权限鉴定
/** * 保存 */ @RequestMapping("/save") public R save (@Validated({AddGroup.class}) @RequestBody Brand brand){ brandService.save(brand); return R.ok(); } /** * 修改 */ @RequestMapping("/update") public R update(@Validated(UpdateGroup.class) @RequestBody Brand brand){ brandService.updateById(brand); return R.ok(); } /** * 修改状态 */ @RequestMapping("/update/status") public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody Brand brand){ brandService.updateById(brand); return R.ok(); }
-
如何自定义校验注解?
-
自定注解
package com.liubo.common.vaild; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Documented @Constraint(validatedBy = { ListValueConstraintValidator.class }) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) public @interface ListValue { String message() default "{com.atguigu.common.valid.ListValue.message}"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; int[] vals() default { }; }
-
实现接口
package com.liubo.common.vaild; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.HashSet; import java.util.Set; public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> { private Set<Integer> set = new HashSet<>(); //初始化方法 @Override public void initialize(ListValue constraintAnnotation) { int[] vals = constraintAnnotation.vals(); for (int val : vals) { set.add(val); } } //判断是否校验成功 /** * * @param value 需要校验的值 * @param context * @return */ @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { return set.contains(value); } }
-
do上面使用
@ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class}) private Integer showStatus;
-