Spring项目:文字花园(一)

news2024/9/20 16:29:23

前言

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

一.准备工作

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("内部错误, 请联系管理员");
    }


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033422.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决No module named ‘tensorflow‘

import tensorflow as tf ModuleNotFoundError: No module named tensorflow 安装合适的tensorflow版本 先查看自己的python版本 或者输入指令&#xff1b;python --version 安装兼容的tensorflow版本&#xff0c;安装指定版本的tensorflow pip install tensorflow-gpu2.3.0…

MVDream 论文学习

论文链接&#xff1a;https://arxiv.org/abs/2308.16512 代码链接&#xff1a;https://github.com/bytedance/MVDream 解决了什么问题&#xff1f; 3D 内容生成是现代游戏和媒体产业中的关键环节&#xff0c;然而这是一个劳动密集型的任务&#xff0c;创建一个 3D 资产就需要…

后端Web之HTTP协议基础介绍

目录 1.HTTP概念 2.HTTP请求协议 3.HTTP响应协议 4.HTTP协议解析 1.HTTP概念 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议。它是万维网数据通信的基础&#xff0c;允许将超…

JVM由那些部分组成,运行流程是什么?

Java 虚拟机 (JVM) 是 Java 运行环境的核心部分&#xff0c;它负责执行 Java 字节码。JVM 由多个不同的组件组成&#xff0c;每个组件都负责不同的任务。下面我将详细介绍 JVM 的主要组成部分及其运行流程。 JVM 的组成部分 类加载器 (Class Loader)&#xff1a; 类加载器负责读…

数据结构 位运算

基础位运算 按位与&#xff08;AND&#xff09; 操作符&#xff1a;&两个位同时位1时&#xff0c;结果位1&#xff0c;否则为0 按位或&#xff08;OR&#xff09; 操作符&#xff1a;|主要有一位是1&#xff0c;那么结果就是1&#xff0c;只有两位都是0的时候&#xff0c;结…

C++ 115类和对象_this指针的用途

学习内容 类和对象_this指针的用途 1.解决名称冲突 2.返回对象本身用 *this 运行结果 代码 #include<iostream> using namespace std;//cout 在这里&#xff0c;没有它会报错//1.解决名称冲突//2.返回对象本身用 *thisclass Person { public:Person(int age){//形参名称…

【深度学习实践】基于深度学习的图像去雾算法-ChaIR-实践

本文介绍一个去雾算法ChaIR的使用方法&#xff0c;可以完成图像去雾&#xff0c;也可以用于图像去雨、去噪音等任务。本文不涉及论文原理&#xff0c;只包含源代码的跑通和使用。 先展示一下效果&#xff1a; 原图去雾 论文&#xff1a;Exploring the potential of channel …

ZAN与Mysten Labs合作推进Web3基础设施开发

Mysten Labs是一家Web3基础设施公司&#xff0c;也是Sui区块链的开发公司&#xff0c;今天宣布与蚂蚁数字科技的技术品牌ZAN建立合作伙伴关系。 通过整合Sui&#xff0c;ZAN旨在加速其Web3应用程序的开发和采用。该合作将专注于为Mysten Labs在两个关键领域提供技术支持&#…

Redis 缓存预热、雪崩、穿透、击穿

缓存预热 缓存预热是什么 缓存预热就是系统上线后&#xff0c;提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候&#xff0c;先查询数据库&#xff0c;然后再将数据缓存的问题&#xff01;用户直接查询事先被预热的缓存数据&#xff01;解决方案 使用 PostConstr…

day2-网络连接网卡配置原理

1.window网卡 理解&#xff1a; window 有 2 块网卡 本地网卡 192.168.13.253 用于连接外网 vmnet8 10.0.0.1(装虚拟机自动生成的 如果没有自动生成…) 虚拟机添加 2 块网卡&#xff1a; 第一块网卡 NAT 模式 添加网卡的时候设置 NAT 模式 2 个作用&#xff0c;用于连接 wi…

Linux服务管理-Nginx进阶

通常会通过rewrite将用户的80请求转化为443请求&#xff0c;也就意味着Nginx需要去做虚拟主机&#xff0c;一个80端口的虚拟主机和一个443端口的虚拟主机&#xff0c;当访问80端口的虚拟主机时返回一个信息让用户去访问443端口的虚拟主机。

技术证书认证-附考试答案-AIGC与大模型通识-英特尔大湾区科技创新中心证书认证

目录 课程简介 面向人群 考核步骤 试题答案 知孤云出岫主页 课程以及考试链接&#xff1a;AIGC与大模型通识 - 英特尔大湾区科技创新中心 【英特尔大湾区科技创新中心】公益新课《AIGC与大模型通识》上线官网&#xff01;首期结业认证进行中&#xff0c;提升AI应用技能&…

解决Element-ui el-tree数据与显示不对应的问题

如图&#xff1a; 后端返回的权限列表&#xff0c;并没有列表这一项&#xff0c;但是由于父节点 版本打包 为选中状态&#xff0c;导致所有子节点都为选中状态。 实现代码如下&#xff1a; <el-treeref"tree":data"records"show-checkboxnode-key&quo…

RuoYi-Vue新建模块

一、环境准备 附:RuoYi-Vue下载与运行 二、新建模块 在RuoYi-Vue下新建模块ruoyi-test。 三、父pom文件添加子模块 在RuoYi-Vue的pom.xml中,引入子模块。 <dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-test</artifactId>&…

【AI人工智能】文心智能体 - 你的专属车牌设计师

引言 自AI盛行以来&#xff0c;不断有各种各样的人工智能产品崭露头角。我们逐步跟着不断产生的人工智能来使自己的工作和生活变得更加智能化&#xff01;那么我们是否能够创造一款专属于自己的人工智能产品呢&#xff1f; 文心智能体平台就给我们提供了这样的机会&#xff0c…

品牌维价的含义和方法

品牌维价是指通过一系列手段和方法&#xff0c;对品牌产品的价格进行统一管理和控制&#xff0c;确保品牌在各个销售渠道都能保持合理稳定的价格体系&#xff0c;从而保障品牌自身以及各级经销商的合理利润。 常见的品牌维价方法可以参考下面这些 品牌自我管控的方法&#xff…

8.2.数据库基础技术-数据模型

概念模型是从用户的角度进行建模的&#xff0c;是现实世界到信息世界的第一抽象&#xff0c;是真正的实体-联系模型。关系模型是二维表的形式表示的实体-联系模型&#xff0c;是将实体-联系模型转换而来的&#xff0c;经过开发人员设计的&#xff1b;网状模型表示实体类型及其实…

【背包蛙】游戏 高端链游 链游开发

#游戏#链游 #深圳软件开发公司#游戏开发公司 以背包整理和物品摆放为核心的策略博弈 那么以背包中的物品&#xff0c;我们就开始了冒险之旅——角色固定拥有3点AP&#xff0c;盾牌或者剑以及后续获得的其他武器&护甲使用绝大部分都需要AP(也包含很多伤害低&次数也受限…

计算数学精解【12】-fortran计算精解(1)

文章目录 概述hello,world环境接收输入与输出 读取csv文件if and select case循环formatread,write format 概述 FORTRAN是英文“FORmulaTRANslator”的缩写&#xff0c;译为“公式翻译器”&#xff0c;它是世界上最早出现的计算机高级程序设计语言&#xff0c;广泛应用于科学…

2024.8.13-算法学习(原创+转载)

一、什么是张量并行&#xff08;Tensor Parallelism&#xff09; &#xff1f; 张量并行&#xff08;Tensor Parallelism&#xff09; 是一种分布式矩阵算法。 随着模型越来越大&#xff0c;模型内的矩阵也越来越大。一个大矩阵的乘法可以拆分成多个小矩阵的运算&#xff0c;…