Grain Mall — Distributed Fundamentals P28~P101 (End)
The first section 1-27 is mainly the environment configuration is particularly difficult, and the next section 28-101 is mainly the front-end code writing and background CRUD operations are more. Because the content is a lot, so I am according to their own want to learn the corresponding point, so I directly skipped the front end, front end code with others complete. The main learning point is focused in the background of the three-level catalog, library table design, OSS and code specifications related learning.
Fork code: gitee.com/empirefree/…
(I suggest that you only use Renren-fast-vue front-end code to learn the back end, and type the rest of the back end code except for CRUD operations)
directory
-
🔥1. Commodities and services
- 1.1 Product tree diagram (Lambda8 code implementation)
- 1.2 Gateway Configuration
- 1.3 Aliyun OSS
- 1.4 Obtaining the Full Path of the Product ID
-
🔥2. Code specification environment
- 2.1. JSR303
- 2.2. Global Exception handling and unified return
- 2.3. Global cross-domain processing
- 2.4 VO, TO
-
🔥 3. Summary
🔥1. Commodities and services
1.1 Product tree diagram (Lambda8 code implementation)
-
Sort class: ID, parentId,sort (weight), List(custom add)
-
Assembly logic: get all items first, then get the first level of goods, recursively sorted to find all sub-items. The following code
1.2 Gateway Configuration
For unified management, the front-end sends all access requests to the gateway. Therefore, the verification code and the port for obtaining subsequent data need to be modified. The modification logic is as follows:
- The original verification code address: http://localhost:8080/renren-fast/captcha.jpg
- Front end launch access address: http://localhost:88/api/captcha.jpg
- Through the Gateway from nacos mapping and path transformation: http://localhost:8080/renrenfast/captcha.jpg (in front of 8080, found in the path from nacos renrenfast port, behind the path is the path of the Gateway conversion)
GateWay request interception and transformation
spring:
cloud:
gateway:
routes:
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?
.*),/$\{segment}
- id: third_party_route
uri: lb://gulimall-third-party
predicates:
- Path=/api/thirdparty/**
filters:
- RewritePath=/api/thirdparty/(?
.*),/thirdparty/$\{segment}
- id: member_route
uri: lb://gulimall-member
predicates:
- Path=/api/member/**
filters:
- RewritePath=/api/(?
.*),/$\{segment}
- id: ware_route
uri: lb://gulimall-ware
predicates:
- Path=/api/ware/**
filters:
- RewritePath=/api/(?
.*),/$\{segment}
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?
.*),/renren-fast/$\{segment}
Copy the code
1.3 Aliyun OSS
The OSS dependency cannot be imported. The following dependency should be used
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
Copy the code
In addition, there are two ways to upload files
- Client ->server-> OSS (not recommended but common) : The server processes the upload
- The server returned to the policy
1.4 Obtaining the Full Path of the Product ID
For the above item tree, give an ID to get the root ID to the ID path
🔥2. Code specification environment
JSR303, global exception handling, global unified return, global cross-domain processing, VO, TO, and PO division
2.1. JSR303
It is the verification annotation of the input parameter, which greatly simplifies the code judgment of the front-end input parameter
/** * null data is not queried */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
/** * Does not exist in the table
@TableField(exist = false)
Copy the code
2.2. Global Exception handling and unified return
In a normal front and back end separation project, the front end has a specification for the parameters, so the back end needs to return a global parameter regardless of the correct or error code
package com.empirefree.gulimall.product.exception;
import com.empirefree.common.exception.BizCodeEnum;
import com.empirefree.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.support.WebExchangeBindException;
import java.util.HashMap;
import java.util.Map;
/ * * * < p > Title: MallExceptionControllerAdvice < / p > * Description: focus on all exceptions * date: 2020/6/1 he * /
@Slf4j
@RestControllerAdvice(basePackages = "com.empirefree.gulimall.product.controller")
public class MallExceptionControllerAdvice {
@ExceptionHandler(value = {WebExchangeBindException.class})
public R handleVaildException(WebExchangeBindException e) {
log.error("Data validation problem {}, exception type: {}", e.getMessage(), e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String, String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError) -> {
// Error field, error message
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMsg()).put("data", errorMap);
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable) {
log.error("Error:", throwable);
returnR.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMsg()); }}Copy the code
2.3. Global cross-domain processing
Because the front-end unified access gateway gateway, the gateway must be configured to allow cross-domain access
package com.empirefree.gulimall.gateway.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 GulimallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(a) {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1. Configure cross-domain
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/ * *", corsConfiguration);
return newCorsWebFilter(source); }}Copy the code
2.4 VO, TO
Since there is a big gap between the input parameter data and the DAO layer, it is necessary to customize some parameters and complete parameter passing combined with code assignment
BeanUtils.copyProperties(group, attrVo);
Copy the code
(I use more XXrequest, XXresponse, XXDTO, XXVO)
🔥 3. Summary
Although the teacher talked about a lot of things in one sentence, it is really important, and I think it needs to be targeted learning, personal feeling of high efficiency
- Distributed related content: NACOS, Gateway, Feign
- Backend related content: oss, tree goods, goods path, global processing (abnormal, cross-domain, unified handling), code specification (JSR303, VO | DTO | DO)
- Database related content: Database table design (Important: personal feeling enlightening to improve backend development)
- Server related content: Docker (still just in the use phase, I still need to improve)
There is no way to learn, but there is no way to learn. Programmers not only to understand the code, but also to understand life, pay attention to me, progress together.