1.使用逆向生成的前后端代码
1.直接拿来用
之前使用renren-generator逆向生成的代码在src\main\resources\src\views\modules\product里有相应的增删改查代码,我们找到相应的代码复制进前端项目
然后,我们为品牌管理添加菜单
当然,可能没有看到新增和批量删除的按钮,那是因为做了权限控制,我们只需要关掉即可,让其永久返回true即可
但是,还有一个问题就是前端项目不够细节,很多功能不够完善,例如基本所有数据库的内容都需要自己输入,显示表头还不够美观等
2.细化页面
1.修改表头
直接改这.....
2.增加switch按钮
进入ElementUI找到表格组件的自定义列模板
我们稍加修改,为这个里加入switch按钮
写一下向后端发送请求的方法(用post请求),只发brandId和showStatus即可
//更新是否展示
updateBrandStatus(data) {
console.log("最新信息", data);
let { brandId, showStatus } = data;
//发送请求修改状态
this.$http({
url: this.$http.adornUrl("/product/brand/update"),
method: "post",
data: this.$http.adornData({ brandId, showStatus }, false),
}).then(({ data }) => {
this.$notify({
title: "成功",
message: `状态更新成功`,
type: "success",
});
});
},
3.修改弹出框的内容
因为弹出框引用了组件
我们直接来到brand-add-or-update.vue里来改
4.logo地址应该由我们上传文件,然后转换成地址放进数据库
1.开通OSS
用这个存储模式
首先进入阿里云,找到对象存储(OSS)
然后开通
2.在弹出框里上传文件
采用服务端签名后上传
先为product项目加入阿里云依赖
<!-- 阿里云OSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
<!--因为是java 9以上版本需要添加JAXB相关依赖:-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
新建模块gulimall-third-party
让它来管理所有第三方软件,为它依赖gulimall-common,和以上依赖,配置nacos,配置key等,在test里写方法上传
3.服务端签名直传
原理
找到示例代码
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Endpoint以华东1(杭州)为例,其他Region请按实际情况填写。
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// 填写Bucket名称,例如examplebucket。
String bucket = "examplebucket";
// 填写Host名称,格式为https://bucketname.endpoint。
String host = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com";
// 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
String callbackUrl = "https://192.168.0.0:8888";
// 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
String dir = "exampledir/";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
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 accessId = credentialsProvider.getCredentials().getAccessKeyId();
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
Map<String, String> 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));
JSONObject jasonCallback = new JSONObject();
jasonCallback.put("callbackUrl", callbackUrl);
jasonCallback.put("callbackBody",
"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
respMap.put("callback", base64CallbackBody);
JSONObject ja1 = JSONObject.fromObject(respMap);
// System.out.println(ja1.toString());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST");
response(request, response, ja1.toString());
} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
} finally {
ossClient.shutdown();
}
}
复制方法体,在第三方服务上新建controller,OssController,写上方法,要在application.yml中配置相关参数
在方法体底部return Map
然后我们希望前端所有请求发给网关来管理,在网关中配置路由
至此可以获取签名
4.联调前端项目
取到文件上传的vue和获取policy的js
来到单文件上传singleUpload,修改上传地址
来到新增表单,引用singleUpload组件
可能出现跨域问题,在OSS管理里允许跨域即可
至此可以不经过我们服务器上传文件到阿里云
5.更改表单验证规则
例如:检索首字母必须是一个字母,排序必须是数字,这里逆向生成的代码都只做了不为空的验证
我们可以使用校验器validator,有三个传参rule:校验规则,value:当前输入的值,callback:校验成功失败之后的回调
先写首字母(不能为空且必须是a-z或者A-Z)
再写排序必须是大于等于0的整数,先让这个输入框接收一个数字
然后判断数字是否符合条件
6.后端校验(9.10.都是后端校验)
因为前端校验可以通过别的提交方式(例如postman)绕过校验,所以要加入后端校验
后端校验主要使用JSR303(Java规范提案303号)的功能
1.给Bean添加校验注解
2.在注入对象前加入注解,启用我们在Bean前加的校验注解
3.自定义错误提示
4.给校验的bean后紧跟-个BindingResult,就可以获取到校验的结果
5.错误提示改写成我们规范的格式
6.后端自定义校验
可以使用@Pattern注解(引号里前后/不需要)
至此后端校验完成,所有的验证注解都可以参照javax.validation.constraints包
7.统一的异常处理
可以使用SpringMVC的@ControllerAdvice功能
1.新建一个包做异常处理
2.注释掉之前的异常处理
那么如何获取异常呢
3.编写统一异常处理类
至此可以将所有的数据校验异常交给统一异常处理类
8.规范化统一异常处理
1.在gulimall-common中编写统一的异常代码和错误提示
写入一个枚举类里(日后回不断添加)
2.在异常处理时提示统一的代码
9.分组校验(数据校验中更高级的功能)(可以完成多场景的复杂校验)
例如,在新增和修改时的校验规则不一样,就要用到分组校验
我们可以在校验注解后加入group属性,也要在common中新建两个空接口AddGroup和UpdateGroup
1.给校验注解上标注什么情况需要校验
2.修改原先Bean前的@Valid为@Validated
3.默认没有指定分组的校验注解不会生效,所以所有的都要加分组
10.自定义校验
可以使用@Pattern加正则表达式,但是有时候光正则表达式无法满足我们的校验规则,我们就需要自己来写
1.编写一个自定义的校验注解
2.编写一个自定义的校验器
3.关联自定义校验器和自定义的校验注解
可以指定多个不同的校验器进行校验