Spring项目:文字花园(一)

前言

实现登录注册功能。
⽤⼾登录成功后, 可以查看所有⼈的博客. 点击 <<查看全⽂>> 可以查看该博客的正⽂内容. 如果该博客 作者为当前登录⽤⼾, 可以完成博客的修改和删除操作, 以及发表新博客

一.准备工作

1.1注入sql (数据准备)

-- 建表SQL
create database if not exists java_blog_spring charset utf8mb4;
USE java_blog_spring;

-- 用户表
DROP TABLE IF EXISTS java_blog_spring.user;
CREATE TABLE java_blog_spring.user(
        `id` INT NOT NULL AUTO_INCREMENT,
        `user_name` VARCHAR ( 128 ) NOT NULL,
        `password` VARCHAR ( 128 ) NOT NULL,
        `github_url` VARCHAR ( 128 ) NULL,
        `delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now(),
        PRIMARY KEY ( id ),
UNIQUE INDEX user_name_UNIQUE ( user_name ASC )) ENGINE = INNODB DEFAULT CHARACTER 
SET = utf8mb4 COMMENT = '用户表';

-- 博客表
drop table if exists java_blog_spring.blog;
CREATE TABLE java_blog_spring.blog (
  `id` INT NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(200) NULL,
  `content` TEXT NULL,
  `user_id` INT(11) NULL,
  `delete_flag` TINYINT(4) NULL DEFAULT 0,
  `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now(),
  PRIMARY KEY (id))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';

-- 新增用户信息
insert into java_blog_spring.user (user_name, password,github_url)values("zhangsan","123456","https://gitee.com/bubble-fish666/class-java45");
insert into java_blog_spring.user (user_name, password,github_url)values("lisi","123456","https://gitee.com/bubble-fish666/class-java45");

insert into java_blog_spring.blog (title,content,user_id) values("第一篇博客","111我是博客正文我是博客正文我是博客正文",1);
insert into java_blog_spring.blog (title,content,user_id) values("第二篇博客","222我是博客正文我是博客正文我是博客正文",2);


1.2创建项目 


1.3配置文件 


spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8&useSSL=false
    username: root
    password: weigang527
    driver-class-name: com.mysql.cj.jdbc.Driver
  mvc:
    favicon:
      enable: false
  profiles:  #多平台配置
    active: dev
# 设置 Mybatis 的 xml 保存路径
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true  #自动驼峰转换
# 配置打印 MyBatis 执行的 SQL
logging:
  file:
    name: logs/springboot.log


1.4测试

点击启动类看项目是否启动成功 


二.项目公共模块

2.1公共层(三层架构)


2.2实体类 

在model层写实体类

1.用户实体(User Info)

package com.example.demo.model;

import lombok.Data;

import java.util.Date;

@Data
public class UserInfo {
    private Integer id;
    private String userName;
    private String password;
    private String githubUrl;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

 2.博客实体(BlogInfo)

package com.example.demo.model;

import lombok.Data;

import java.util.Date;

@Data
public class BlogInfo {
    private Integer id;
    private String title;
    private String content;
    private Integer userId;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

 3.结果实体(Result)

3.1使用枚举

package com.example.demo.enums;

public enum ResultStatus {
    SUCCESS,
    FAIL,
    NOLOGIN;
}

3.2创建结果实体类

package com.example.demo.model;

import com.example.demo.enums.ResultStatus;
import lombok.Data;

@Data
public class Result<T> {
    //业务码 200-成功  -1  失败   -2 未登录
    private ResultStatus code;
    //错误信息
    private String errMsg;
    //接口响应的数据
    private T data;

    public static <T> Result<T> success(T data){
        Result result = new Result();
        result.setCode(ResultStatus.SUCCESS);
        result.setErrMsg("");
        result.setData(data);
        return result;
    }

    public static <T> Result<T> fail(String errMsg){
        Result result = new Result();
        result.setCode(ResultStatus.FAIL);
        result.setErrMsg(errMsg);
        result.setData(null);
        return result;
    }

    public static <T> Result<T> fail(String errMsg, T data){
        Result result = new Result();
        result.setCode(ResultStatus.FAIL);
        result.setErrMsg(errMsg);
        result.setData(data);
        return result;
    }

}

代码解读:

这个Result<T>类是一个泛型类,用于封装API接口的响应结果。它包含了三个主要属性:业务码(code)、错误信息(errMsg)和接口响应的数据(data)。这个类使用了Lombok库的@Data注解来自动生成getter和setter方法,以及equalshashCodetoString方法,从而简化了代码量。

Result<T>类定义了一个泛型T,这意味着它可以携带任何类型的数据作为响应体。这对于构建RESTful API特别有用,因为你可以根据API的不同需求返回不同类型的数据。

类中定义了三个静态方法,用于快速创建Result实例:

  1. success(T data):这个方法用于创建表示操作成功的Result实例。它设置业务码为ResultStatus.SUCCESS(假设这是一个表示成功的枚举值),错误信息为空字符串,并将传入的数据作为响应数据。

  2. fail(String errMsg):这个方法用于创建表示操作失败的Result实例,但不包含任何响应数据。它设置业务码为ResultStatus.FAIL(假设这是一个表示失败的枚举值),设置传入的错误信息,并将响应数据设置为null

  3. fail(String errMsg, T data):这个方法也是用于创建表示操作失败的Result实例,但与上一个方法不同,它允许你传入一个额外的数据对象作为响应体。这在你需要向客户端返回一些额外信息(尽管操作失败了)时非常有用。它同样设置业务码为ResultStatus.FAIL,并设置传入的错误信息和数据。


2.3统一结果返回

创建一个接口来会接收实体类的统一结果返回

1.统一结果返回:

package com.example.demo.config;

import com.example.demo.model.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return false;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result){
            return body;
        }
        if (body instanceof String){
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body);
    }
}

代码解读:

这段代码定义了一个ResponseAdvice类,它实现了Spring MVC的ResponseBodyAdvice接口,用于在控制器方法返回响应体之前对其进行全局处理。具体来说,这个类的作用是在每个控制器方法的响应体被写出之前,检查响应体的类型,如果不是Result类型(这是一个自定义的封装了响应结果、业务码和错误信息的类),则将其包装成Result类型,以确保所有对外暴露的API响应都遵循统一的格式。 

2.4统一异常处理 

2.统一异常处理:

代码:

package com.example.demo.config;

import com.example.demo.model.Result;
import lombok.extern.slf4j.Slf4j;
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.servlet.resource.NoResourceFoundException;

@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionHandle {

    @ExceptionHandler
    public Result handle(Exception e){
        log.error("发生异常, e:", e);
        return Result.fail("内部错误, 请联系管理员");
    }

    @ExceptionHandler
    public Result handle(NoResourceFoundException e){
        log.error("文件不存在:", e.getMessage());
        return Result.fail("内部错误, 请联系管理员");
    }


}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值