栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

电商生鲜网站开发(三)——后台开发:商品分类模块-Redis/Swagger/统一身份校验/IDEA技巧

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

电商生鲜网站开发(三)——后台开发:商品分类模块-Redis/Swagger/统一身份校验/IDEA技巧

电商生鲜网站开发(三)——后台开发:商品分类模块-Redis/Swagger/统一身份校验/IDEA技巧 分类层级

在商品分类上需要继续做归类操作

分类设置成三级

层级太深的弊端:对用户不友好,不利于查找;后台管理部方便

分类模块主要功能

分类数据的设置

根据分类的父级目录递归查找

接口与表设计

https://blog.csdn.net/a2272062968/article/details/123385857

分类接口开发

跟用户接口类似

参数校验
注解说明
@Valid需要验证
@NotNull非空
@Max(Value)最大值
@Size(max,min)字符串长度范围限制

在前台传入的实体类定义中参数上增加对应规则的注解即可,可以增加多个规则

package com.imooc.mall.model.request;

import lombok.Data;

import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;


@Data
public class AddCategoryReq {
    @Size(min = 2,max = 5)
    private String name;
    @NotNull
    @Max(3)
    private Integer type;

    @NotNull(message = "parentId不能为null")
    private Integer parentId;

    @NotNull(message = "orderNum不能为null")
    private Integer orderNum;
}

增加校验后即可拦截不规范的数据,我们捕捉注解抛出的异常就可以获取到提示信息

去之前的GloalExceptionHandler拦截异常类中编写异常过滤器

package com.learn2333.mall.exception;
//拦截异常
@ControllerAdvice
@Slf4j
public class GloalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GloalExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handleException(Exception e) {
        logger.error("Default Exception:", e);
        return ApiRestResponse.error(MallExceptionEnum.SYSTEM_ERROR);
    }

    @ExceptionHandler(MallException.class)
    @ResponseBody
    public Object handleImoocMallException(MallException e) {
        logger.error("MallException:", e);
        return ApiRestResponse.error(e.getCode(), e.getMessage());
    }

    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiRestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("MethodArgumentNotValidException:", e);
        return handleBindingResult(e.getBindingResult());
    }

    private ApiRestResponse handleBindingResult(BindingResult result) {
        //把异常处理为对外暴露的提示
        List list = new ArrayList<>();
        if (result.hasErrors()) {
            List allErrors = result.getAllErrors();
            // itli
            for (ObjectError objectError : allErrors) {
                String message = objectError.getDefaultMessage();
                list.add(message);
            }
        }
        if (list.size() == 0) {
            return ApiRestResponse.error(MallExceptionEnum.REQUEST_PARAM_ERROR);
        }
        return ApiRestResponse.error(MallExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());
    }
}

异常枚举所有错误码
package com.learn2333.mall.exception;


public enum MallExceptionEnum {
    NEED_USER_NAME(10001,"用户名不能为空"),
    NEED_PASSWORD(10002,"密码不能为空"),
    NEED_TOO_SHORT(10003,"密码长度不能小于8位"),
    NAME_EXISTED(10004,"不允许重名"),
    INSERT_FAILED(10005,"插入失败,请重试"),
    WRONG_PASSWORD(10006,"登录密码错误,请重试"),
    NEED_LOGIN(10007,"用户未登录,请登录"),
    UPDATE_FAILD(10008,"更新失败,请重试"),
    NEED_ADMIN(10009,"无管理员权限"),
    PARA_NOT_NULL(10010,"参数不能为空"),
    CREATE_FAILED(10011,"新增失败"),
    REQUEST_PARAM_ERROR(10012,"参数错误"),
    DELETE_FAILED(10013,"删除失败"),
    MKDIR_FAILED(10014,"文件夹创建失败"),
    UPLOAD_FAILED(10015,"图片上传失败"),
    NOT_SALE(10016,"商品状态不可售"),
    NOT_ENOUGH(10017,"商品库存不足"),
    CART_EMPTY(10018,"购物车已勾选的商品为空"),
    NO_ENUM(10019,"未找到对应的枚举"),
    NO_ORDER(10020,"订单不存在"),
    NO_YOUR_ORDER(10021,"订单不属于你"),
    WRONG_ORDER_STATUS(10021,"订单不符"),
    SYSTEM_ERROR(20000,"系统异常");
    
    Integer code;
    
    String msg;


    MallExceptionEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
Swagger自动生成API文档 引入依赖

pom

        
            io.springfox
            springfox-swagger2
            2.9.2
        
        
            io.springfox
            springfox-swagger-ui
            2.9.2
        
开启

入口类上增加@EnableSwagger2注解开启自动生成api文档

修改配置

config包下修改配置文件

package com.learn2333.mall.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.documentationType;
import springfox.documentation.spring.web.plugins.Docket;


@Configuration
public class SpringFoxConfig {

    //访问http://localhost:8083/swagger-ui.html可以看到API文档
    @Bean
    public Docket api() {
        return new Docket(documentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("生鲜网站")
                .description("")
                .termsOfServiceUrl("")
                .build();
    }
}
配置MVC Config Swagger地址映射
package com.learn2333.mall.config;

import com.learn2333.mall.common.Constant;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class MallWebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        registry.addResourceHandler("/images
public class AdminFilter implements Filter {

    @Autowired
    UserService userService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
            FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpSession session = request.getSession();
        User currentUser = (User) session.getAttribute(Constant.MALL_USER);
        if (currentUser == null) {
            PrintWriter out = new HttpServletResponseWrapper(
                    (HttpServletResponse) servletResponse).getWriter();
            out.write("{n"
                    + "    "status": 10007,n"
                    + "    "msg": "NEED_LOGIN",n"
                    + "    "data": nulln"
                    + "}");
            out.flush();
            out.close();
            return;
        }
        //校验是否是管理员
        boolean adminRole = userService.checkAdminRole(currentUser);
        if (adminRole) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            PrintWriter out = new HttpServletResponseWrapper(
                    (HttpServletResponse) servletResponse).getWriter();
            out.write("{n"
                    + "    "status": 10009,n"
                    + "    "msg": "NEED_ADMIN",n"
                    + "    "data": nulln"
                    + "}");
            out.flush();
            out.close();
        }
    }

    @Override
    public void destroy() {

    }
}
配置过滤器生效范围

这样,当请求路径带有以下范围时,过滤器拦截生效,进行上面的管理员身份校验

package com.learn2333.mall.config;

import com.learn2333.mall.filter.AdminFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class AdminFilterConfig {

    @Bean
    public AdminFilter adminFilter() {
        return new AdminFilter();
    }

    @Bean(name = "adminFilterConf")
    public FilterRegistrationBean adminFilterConfig() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(adminFilter());
        filterRegistrationBean.addUrlPatterns("/admin/category
@Configuration
@EnableCaching
public class CachingConfig {

    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
        
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(30));	//超时时间30s

        RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration);
        return redisCacheManager;
    }
}
需要缓存的实体类实现接口

要想让分类写入缓存还必须为对应的实体类实现Serializable接口

public class CategoryVO implements Serializable 
验证缓存生效

**方法一:**在30秒内调用的缓存方法都会返回之前查询的缓存内容;可以在需要缓存的内容方法中打断电测试,调用方法时没有执行方法而是直接从缓存中读取,速度显著提升

**方法二:**在终端使用keys查看redis中的内容

IDEA调试技巧 统一开关

让所有断点失效

条件断点

指定条件成立时生效

单步调试

表达式求值

可以输入任意表达式查询内部的内容

总结

知识点:参数校验、Swagger、统一鉴权、Redis整合、调试功能

开发常见问题:参数手动校验、项目不用缓存、不善用调试

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777322.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号