7.商品服务-API品牌管理(59-69)

59.使用逆向工程的前后端代码

1.首先在‘系统管理’-‘菜单管理’里面进行新增‘品牌管理’
2.将自动生成的brand.vue和brand-add-or-update.vue新增到前端product目录下
3.修改权限,以用来展示‘新增’‘删除’按钮,将index.js export funcation isAuth(){}
全部返回true

60.效果优化与快速显示开关

1.修改webpack.base.conf.js里的const createLintingRule{}全部注释掉;为了消除控制台代码校验总是报错;
2.加入开关

在这里插入图片描述

3.修改弹窗显示状态开关组件;brand-add-or-updaye.vue

在这里插入图片描述
首先:做好以上的所有准备工作后,我们首先来修改‘显示状态’
在这里插入图片描述

1.为我们的开关来绑定change事件

在这里插入图片描述
在这里插入图片描述

后台Controller还有renren默认生成的代码

61.云存储开通与使用

由于系统架构分为 单体应用 与 分布式应用 两种风格
1.单体架构:文件上传到服务器,获取文件,也是从该服务器获取的
2.分布式:首次文件上传,由于负载均衡到B服务器,而获取文件,有可能从A服务器获取;会
出现文件找不到的现象;

解决方法

不同服务之间来获取文件,都来单独的文件存储服务里获取;

分类:
1.自建服务器:FastDFS vsftpd 搭建复杂、维护成本高、前期费用高;
2.云存储:阿里云存储对象、七牛云存储 即开即用、无需维护、按量收费;

在这里插入图片描述
1.注册阿里云账号
在这里插入图片描述

SpringCloud Alibaba-OSS
对象存储服务(Object Storage Service,OSS)是一种海量、安全、低成本、高可靠的云存储服务,
适合存放任意类型的文件。容量和处理能力弹性扩展,多种云存储类型供选择,全面优化存储成本。

2.首次,需要开通OSS,开通过以后,进入自己的控制台

1.创建Bucket,也就是创建一个桶;建议一个项目创建一个Bucket;
a.输入名称
b.选择区域
c.存储类型选择‘低频访问’
d.同城冗余存储 ‘关闭’
e.读写权限 ‘公共读’
f.服务器端加密:无
g.实时日志查询:不开通

在这里插入图片描述
3.阿里云对象存储-服务端签名后直传
在这里插入图片描述

62.OSS整合测试

第一种:先测试
1.安装SDK,gulimall-product pom.xml

<dependency>
	<groupId>com.aliyun.oss</groupId>
	<artifactId>aliyun-sdk-oss</artifactId>
	<version>3.5.0</version>
</dependency>

2.写测试类

@Test
public void testUpload() throws FileNotFoundException {
	// Endpoint以杭州为例,其它Region请按照实际情况填写
	String endpoint = "oss-cn-beijing.aliyuncs.com";
	// 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问活日常运维
	String accessKeyId = "";
	String accessKeySecret = "";

	//创建OSSClient示例
	OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
	//上传文件流
	InputStream inputStream = new FileInputStream();
	ossClient.putObject(,,inputStream);
	//关闭OSSClient
	ossClient.shutdown();
}
1.获取endpoint 在概览里

在这里插入图片描述

2.获取各种key 选择使用‘子用户’的key

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.修改权限

在这里插入图片描述
第二种:用SpringCloud Alibaba OSS

<dependency>
	<groupId>com.alibaba.cloud</grouId>
	<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>

63.OSS获取服务端签名

1.创建gulimall-thired-party(选择web、openfeign,依赖gulimall-common)
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-third-party</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gulimall-third-party</name>
    <description>第三方服务</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.atguigu.gulimall</groupId>
            <artifactId>gulimall-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--        阿里云上传图片-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.将third-party配置到注册中心、发现
在这里插入图片描述
在这里插入图片描述
修改application.yml
在这里插入图片描述
修改main 新增注册发现
在这里插入图片描述
3.新建OSSController

package com.atguigu.gulimall.thirdparty.controller;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.atguigu.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OssController {
    @Autowired
    OSS ossClient;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;


    @RequestMapping("/oss/policy")
    public R policy() {



        //https://gulimall-hello.oss-cn-beijing.aliyuncs.com/hahaha.jpg

        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
//        String callbackUrl = "http://88.88.88.88:8888";
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir = format + "/"; // 用户上传文件时指定的前缀。

        Map<String, String> respMap = null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            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 = new LinkedHashMap<String, String>();
            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));
            // respMap.put("expire", formatISO8601Date(expiration));


        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        }

        return R.ok().put("data",respMap);
    }
}

4.以上就成功的获取到签名;修改网关

        - id: third_party_route
          uri: lb://gulimall-third-party
          predicates:
            - Path=/api/thirdparty/**
          filters:
            - RewritePath=/api/thirdparty/(?<segment>.*),/$\{segment}

64.OSS前后端调试上传

1.新增upload
在这里插入图片描述
在这里插入图片描述
2.引入但文件上传组件
在这里插入图片描述
在这里插入图片描述

在components:{ SingleUpload }

3.修改OSS的跨域问题

65.表单校验&自定义校验器

在这里插入图片描述
自定义校验
在这里插入图片描述

66.JSR303数据校验

使用步骤
1.给Bean添加校验注解:javax.validation.constraints,并定义自己的message提示
2.开启校验功能@Valid 效果:校验错误以后会有默认的响应
3.给校验的bean后紧跟一个BindingResult,就可以获取到校验的结果

在这里插入图片描述

@NotEmpty与@NotBlank区别:
@NotEmpty:必须不是null或者empty
@NotBlank:必须不是null并且包含至少一个非空字符

在这里插入图片描述

package com.atguigu.gulimall.product.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import org.hibernate.validator.constraints.URL;

/**
 * 品牌
 * 
 * @author niuniu
 * @email 13303835433@163.com
 * @date 2020-07-03 09:59:53
 */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 品牌id
	 */
	@TableId
	private Long brandId;
	/**
	 * 品牌名
	 */
	@NotBlank(message = "品牌名必须添加")
	private String name;
	/**
	 * 品牌logo地址
	 */
	@URL(message="logo必须是一个合法的url地址")
	private String logo;
	/**
	 * 介绍
	 */
	private String descript;
	/**
	 * 显示状态[0-不显示;1-显示]
	 */
	private Integer showStatus;
	/**
	 * 检索首字母
	 */
	@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是一个字母")
	private String firstLetter;
	/**
	 * 排序
	 */
	@Min(value = 0,message = "排序必须大于等于0")
	private Integer sort;

}

67.统一异常处理

统一异常处理
1.@ControllerAdvice

集中处理所有异常
在这里插入图片描述
GulimallExceptionControllerAdvice

package com.atguigu.gulimall.product.exception;

import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.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.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.Map;

/**
 * 集中处理所有异常
 */
@Slf4j
//@ResponseBody
//@ControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
public class GulimallExceptionControllerAdvice {


    @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());
    }


}

gulimall-common

package com.atguigu.common.exception;

/***
 * 错误码和错误信息定义类
 * 1. 错误码定义规则为5为数字
 * 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常
 * 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式
 * 错误码列表:
 *  10: 通用
 *      001:参数格式校验
 *  11: 商品
 *  12: 订单
 *  13: 购物车
 *  14: 物流
 *
 *
 */
public enum BizCodeEnume {
    UNKNOW_EXCEPTION(10000,"系统未知异常"),
    VAILD_EXCEPTION(10001,"参数格式校验失败"),
    PRODUCT_UP_EXCEPTION(11000,"商品上架异常");


    private int code;
    private String msg;
    BizCodeEnume(int code,String msg){
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

68.JSR303分组校验

说明:例如BrandEntity的brandId字段,在新增的时候,id是自增,不用校验;在修改的时候,id必须指定;
/**
  *品牌id
  */
@NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})
@Null(message="新增不能指定id",groups = {AddGroup.class})
@TableId
private Long brandId

在valid/gulimall-common声明两个接口

在这里插入图片描述
在gulimall-product/brandController的save方法上加上注解
在这里插入图片描述

69.JSR303自定义校验注解

1.编写一个自定义的校验注解
2.编写一个自定义的校验器
3.关联自定义的校验器和自定义的校验注解

1.在gulimall-common的pom.xml文件引入依赖

<dependency>
	<groupId>javax.validation</groupId>
	<artifactId>validation-api</artifactId>
	<version>2.0.1.Final</version>
</dependency>

2.在gulimall-common的valid包下创建ListValue接口


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coder-N

踏实 勤奋 努力 拼搏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值