页面跳转需要保证 域名以及协议,端口号 一致在页面跳转时才不会出现跨域的问题
springMvc中提供了跨域问题的解决方案 (可以参考官网信息)
package com.dgj.cubemall.cubemallgateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlbasedCorsConfigurationSource;
@Configuration
public class CubeMallCorsConfig {
@Bean
public CorsWebFilter corsWebFilter(){
CorsConfiguration config = new CorsConfiguration();
// 设置为true 可以携带cookie信息
config.setAllowCredentials(true);
// 允许跨域访问的来源(* 代表允许所有的请求地址访问)
config.addAllowedOrigin("https://localhost:8001");
// * 允许携带所有的请求头信息
config.addAllowedHeader("*");
// * 允许所有的请求方式(get,post,option等)
config.addAllowedMethod("*");
UrlbasedCorsConfigurationSource source = new UrlbasedCorsConfigurationSource();
//
private List getChildrenListInfo(CategoryEntity currentMenu, List categoryEntityList) {
List childrenList = categoryEntityList.stream().filter(
//过滤出当前菜单所匹配的子菜单信息 currentMenu.getId = categoryEntity.getParentId
categoryEntity -> currentMenu.getId().equals(categoryEntity.getParentId())
).map(
menu -> {
menu.setChildrenList(getChildrenListInfo(menu,categoryEntityList));
return menu;
}
).collect(Collectors.toList());
return childrenList;
}
3.mybatsi-plus 逻辑删除
步骤1: 配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig
- 例: application.yml
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
步骤2-实体类字段上加上-tablelogic注解步骤2: 实体类字段上加上@TableLogic注解
@TableLogic private Integer deleted;
@Override public void removeMenusById(ListasList) { //TODO 检查当前要删除的菜单是否被别的地方引用 //逻辑删除 使用mybatisPlus baseMapper.deleteBatchIds(asList); }
0904
4.图片上传功能的实现创建 Bucket 阿里云 对象存储 oss 创建账号,阿里云有代码实例
@RestController
@Slf4j
@RequestMapping("oss")
public class OssController {
@Autowired
private OSS ossClient;
@Value("${spring.cloud.alicloud.access-key}")
private String accessId; // 请填写您的AccessKeyId。
@Value("${spring.cloud.alicloud.secret-key}")
private String accessKey; // 请填写您的AccessKeySecret。
@Value("${spring.cloud.alicloud.oss.endpoint}")
private String endpoint; // 请填写您的 endpoint。
@Value("${spring.cloud.alicloud.bucket}")
private String bucket; // 请填写您的 bucketname 。
private String DATEFORMAT = "yyyy-MM-dd";
@GetMapping("policy")
public R policy(){
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
// callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
//增加上传目录的结构
String simpleDateFormat = new SimpleDateFormat(DATEFORMAT).format(new Date());
// String dir = "user-dir-prefix/"; // 用户上传文件时指定的前缀。
String dir = simpleDateFormat + "/";
Map respMap = new linkedHashMap(16);
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
// PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.tobase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
respMap.put("accessid", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
} catch (Exception e) {
// Assert.fail(e.getMessage());
log.info(e.getMessage());
} finally {
ossClient.shutdown();
}
return R.ok().put("data",respMap);
}
}
#mybatisPlus
server:
port: 30000
servlet:
context-path: /third
# 注册中心
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
alicloud: #对象存储oss
oss:
endpoint: oss-cn-hangzhou.aliyuncs.com
access-key: xxx
secret-key: xxx
bucket: cube-mall-xxx
application:
name: third-party
5.MybatisPlus分页插件
添加配置,传递参数为map键值对的形式
@Configuration
@MapperScan("com.dgj.cubemall.product.dao")
public class MyBatisPlusConfig {
// 最新版
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//分页拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
//service实现
@Service("brandService")
public class BrandServiceImpl extends ServiceImpl implements BrandService {
@Override
public PageUtils queryPage(Map params) {
//编写条件查询,按名称,id等信息模糊查询
String key = params.get("key").toString();
//查询使用的条件
QueryWrapper queryWrapper = new QueryWrapper<>();
//封装查询条件
if (StringUtils.isNotEmpty(key)) {
//数据库中的字段,值(按照id精准查询,或者按照名称模糊查询)
queryWrapper.eq("id",key).or().like("name",key);
}
IPage page = this.page(
new Query().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
}
0908
6.后端参数校验BindingResult result // controller 获取到所有的报错信息
if(result.hasErrors()){
Map map = new HashMap<>(16);
//1.获取校验错误的结果
result.getFieldErrors().forEach(fieldError -> {
//获取错误属性名称以及错误的提示信息
String field = fieldError.getField();
String defaultMessage = fieldError.getDefaultMessage();
map.put(field,defaultMessage);
});
return R.error(404,"提交的数据不合法").put("data",map);
}else {
brandService.save(brand);
return R.ok();
}
同一个实体类定义不同的验证规则,针对不同的接口(分类情况下使用@Validated注解,指定分组信息,而且校验注解后要加分组信息)
public interface UpdateGroup {
}
public interface SaveGroup {
}
调用接口信息
@PostMapping("/save")
public R save(@Validated(SaveGroup.class) @RequestBody BrandEntity brand){
brandService.save(brand);
return R.ok();
}
@RequestMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}
实体类对象
@Data
@TableName("tb_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
@NotNull(message = "修改id不能为空",groups = {UpdateGroup.class})
@Null(message = "新增id必须为空",groups = {SaveGroup.class})
private Integer id;
@NotBlank(message = "品牌名必须提交",groups = {UpdateGroup.class,SaveGroup.class})
private String name;
@NotBlank(message = "图片地址不能为空",groups = {UpdateGroup.class,SaveGroup.class})
@URL(message = "log必须是一个合法的地址",groups = {UpdateGroup.class,SaveGroup.class})
private String image;
@NotEmpty(groups = {UpdateGroup.class,SaveGroup.class})
@Pattern( regexp = "^[a-zA-Z]$",message = "检索首字母必须是字母",groups = {UpdateGroup.class,SaveGroup.class})
private String letter;
@NotNull(groups = {UpdateGroup.class,SaveGroup.class})
@Min(value = 0,message = "排序字段必须大于等于0",groups = {UpdateGroup.class,SaveGroup.class})
private Integer seq;
}
7.全局异常处理
package com.dgj.cubemall.product.exception;
import com.dgj.cubemall.common.exception.CubeMallEnum;
import com.dgj.cubemall.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;
@RestControllerAdvice(basePackages = "com.dgj.cubemall.product.controller")
@Slf4j
public class CubemallExceptionControllerAdvice {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handlerValidException(MethodArgumentNotValidException e){
log.error("数据校验出现问题{},异常类型{}",e.getMessage(),e.getCause());
Map map = new HashMap<>(16);
//1.获取校验错误的结果
BindingResult bindingResult = e.getBindingResult();
bindingResult.getFieldErrors().forEach(fieldError -> {
//获取错误属性名称以及错误的提示信息
String field = fieldError.getField();
String defaultMessage = fieldError.getDefaultMessage();
map.put(field,defaultMessage);
});
return R.error(CubeMallEnum.VALID_EXCEPTION.getCode(),CubeMallEnum.VALID_EXCEPTION.getMessage()).put("data",map);
}
@ExceptionHandler(value = Throwable.class)
public R handlerValidException(Throwable throwable){
log.error("出现错误",throwable);
return R.error(CubeMallEnum.UNKNOWN_EXCEPTION.getCode(),CubeMallEnum.UNKNOWN_EXCEPTION.getMessage()).put("data","未知异常");
}
}
8.接口状态码的定义与使用
枚举的方式定义状态码,使用的时候调用枚举了,参考上面参数校验的状态码定义
package com.dgj.cubemall.common.exception;
public enum CubeMallEnum {
//枚举提前准备好数据类型
UNKNOWN_EXCEPTION(100000,"系统未知异常"),
VALID_EXCEPTION(10001,"参数格式校验异常");
private Integer code;
private String message;
CubeMallEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
}



