Skip to content
View Cvxiaozhu's full-sized avatar
Block or Report

Block or report Cvxiaozhu

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Please don't include any personal information such as legal names or email addresses. Maximum 100 characters, markdown supported. This note will be visible to only you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
Cvxiaozhu/README.MD

个人博客

心得:
    1、了解基本包结构 
        controller (处理前端发来的请求和回传的响应)
        service (前端具体的业务在这个包下实现)
        mapper ((dao)持久层开发,与数据库进行交互)
        entity (实体类,模型的对象化)
        config (配置类,相关框架的配置可以通过@Configuration标识 并且实现或者继承)
        vo (封装从后台传入前台的数据)
        dto (封装从前台传入后台的数据)
        exception (自定义的全局异常处理)
        constants (常量类,将字面量写在这里面)
    2、熟悉了一些项目的开发流程;
    3、学习一些设计思想;
    4、将先前所学的知识应用起来

分析业务

    分为前后台, 因此考虑分成多个模块实现,同时对于相同的业务获取工具类配置类,采用
    一个公共的框架管理,减少重复代码量,同样的因为多模块的问题,通过maven管理的依赖
    变得冗余了,有可能也会因为版本不兼容而产生冲突,所以可以利用Maven的继承机制对需
    要的依赖进行版本控制统一管理。
    
    前台页面
        1、首页
        2、分类
        3、友链
        4、个人中心(这里需要用户登录才能访问)
    
    后台页面
        1、首页
        2、发表博文
        3、系统管理
        4、用户管理

前台模块 zhu-blog

可以让任何人不用登录进行访问,但是如果访客想要评论就需要进行登录操作(普通用户)
此时登录可以通过Security + Jwt权限认证既能够保存用户的信息安全,而且能够让用户
在之后的一段时间内免登录。之后进行一个普通的CRUD;中间具体按照MVC的模式进行业务开发
同时为了简化持久层的开发,引入了mybatis持久层框架,简化持久层的开发。

后台模块 zhu-admin

只有拥有管理员权限的用户能够进入,必须登录

1、博客前台

一些常用类

前后端数据统一类

package com.zhu.blog.entity;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.zhu.blog.enums.AppHttpCodeEnum;

/**
 * @author GH
 * @Description: 前后端数据交换格式统一
 * @date 2023/2/16 16:13
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@SuppressWarnings("unchecked")
public class ResponseResult<T>{

    private Integer code;
    private String msg;
    private T data;


    public ResponseResult() {
        this.code = AppHttpCodeEnum.SUCCESS.getCode();
        this.msg = AppHttpCodeEnum.SUCCESS.getMsg();
    }

    public ResponseResult(Integer code, T data) {
        this.code = code;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

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

    public static ResponseResult errorResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.error(code, msg);
    }
    public static ResponseResult okResult() {
        ResponseResult result = new ResponseResult();
        return result;
    }
    public static ResponseResult okResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.ok(code, null, msg);
    }

    public static ResponseResult okResult(Object data) {
        ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getMsg());
        if(data!=null) {
            result.setData(data);
        }
        return result;
    }

    public static ResponseResult errorResult(AppHttpCodeEnum enums){
        return setAppHttpCodeEnum(enums,enums.getMsg());
    }

    public static ResponseResult errorResult(AppHttpCodeEnum enums, String msg){
        return setAppHttpCodeEnum(enums,msg);
    }

    public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
        return okResult(enums.getCode(),enums.getMsg());
    }

    private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String msg){
        return okResult(enums.getCode(),msg);
    }

    public ResponseResult<?> error(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data) {
        this.code = code;
        this.data = data;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
        return this;
    }

    public ResponseResult<?> ok(T data) {
        this.data = data;
        return this;
    }

    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;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


}

security权限认证的的配置类

package com.zhu.blog.config;

/**
 * @author GH
 * @Description:
 * @date 2023/3/3 20:04
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    /**
     * 用户密码加密类型
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 解决跨域请求问题
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //关闭csrf
                .csrf().disable()
                //不通过Session获取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 对于登录接口 允许匿名访问
                .antMatchers("/login").anonymous()
                .antMatchers("/logout").authenticated()
                .antMatchers("/user/userInfo").authenticated()
                // 除上面外的所有请求全部不需要认证即可访问
                .anyRequest().permitAll();

        // 配置异常处理器
        http.exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .accessDeniedHandler(accessDeniedHandler);

        // 关闭默认的退出登录功能
        http.logout().disable();

        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //允许跨域
        http.cors();
    }

    /**
     * security权限校验
     *
     * @return
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

遇到的问题

逻辑问题

在文章实体类中有几个字段设置了自动填充, 但是填充的过程中需要拿到当前登录的用户id, 而前台开发中实现了一个redis缓存浏览量;在这一段过程中 设置了一个定时任务,每隔一定时间更新一次,这是就会不断 地更新数据库中的几个字段,而此时又没有用户登录,从而导致了空指针异常

表设计问题1

文章和标签进行了关联,同时增加了一张表存储它们的关系,将两个值都设置为主键 所以在进行持久层操作的时候都无法将其删除或者更新
通过以下方式解决

表设计问题2

对于角色用户表,其中保存了角色用户关联关系,而在进行角色信息删除时也会影响到这张表 后期再解决

联合前端问题

后台的菜单管理中对于新增菜单 对于没有跟前端做好统一因此如果添加了目录后,会影响页面的展示问题 因此对于菜单管理,不要进行增删操作

Popular repositories

  1. Cvxiaozhu Cvxiaozhu Public

    没事看看

    Vue 1

  2. gitskills gitskills Public

    1

  3. Chinese-Top-Charts Chinese-Top-Charts Public

    Java 1

  4. music-website music-website Public

    Vue

  5. MarkDown MarkDown Public

  6. vhr vhr Public

    Forked from lenve/vhr

    微人事是一个前后端分离的人力资源管理系统,项目采用SpringBoot+Vue开发。

    Java