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

springboot引入vue(spring boot+vue)

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

springboot引入vue(spring boot+vue)

本文章记录我在写SpringBoot为后端,Vue为前端的项目时,使用到的技巧,碰到的问题,本文持续更新

前端 项目运行时浏览器自动打开

在package.json文件中的scripts配置项:

"scripts": {
   "serve": "vue-cli-service serve --open", // 在启动项后面添加--open
   "build": "vue-cli-service build",
   "lint": "vue-cli-service lint"
},
关闭eslint校验工具(不建议关闭,建议修改规则)

在Vue.config.js配置文件中

module.exports = {
    // 关闭eslint
    lintOnSave:false
}
Vue3使用路由

首先添加路由的依赖

yarn add vue-router

与Vue2的自动新建不同,vue-router 4.x似乎不会自动新建router.js文件,所以需要手动新建

import { createRouter, createWebHistory } from "vue-router";

import Main from "../view/Main.vue";

const routes = [
  {
    path: "/",
    name: "Main",
    component: Main
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

新版的Vue-router不再是通过new Router新建路由类,而是同过createRouter函数

其他的改动见官方文档:https://router.vuejs.org/zh/guide/migration/index.html

新建了路由文件后,在入口文件main.js中,使用use的方法挂载

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router/router";

const app = createApp(App);

app.use(router);

app.mount("#app");

控制路由跳转

由于在Vue3的setup中无法像Vue2那样通过this访问$router,Vue-Router官方提供了代替的useRouter函数

import { useRouter, useRoute } from 'vue-router'

export default {
  setup() {
    const router = useRouter()
    const route = useRoute()

    function pushWithQuery(query) {
      router.push({
        name: 'search',
        query: {
          ...route.query,
        },
      })
    }
  },
}

注:在模板中依然可以访问到$router和$route,所以在setup中无需抛出router和route

使用vite创建的项目读取.env配置文件配置项

之前的process方式已失效,使用全新的import.meta.env读取配置,且配置前缀必须为VITE

例:

.env文件:

VITE_SERVICE_URL = 'http://127.0.0.1:8000'

读取:

console.log(import.meta.env.VITE_SERVICE_URL)

其他详细配置:https://vitejs.cn/guide/env-and-mode.html

后端 修改时间格式为标准格式

将:2019-10-30T06:18:46.000+00:00修改为标准格式yyyy-MM-dd HH:mm:ss的时间

SpringBoot中

在application配置文件中设置

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
逻辑删除

1.首先配置好MybatisPlus的逻辑删除插件,插件配置在编写好的MyBatisPlus的配置类中即可

@Bean
public ISqlInjector sqlInjector(){
	return new LogicSqlInjector();
}

2.为实体类中需要进行逻辑删除的字段添加上@TableLogic注解

@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
@TableLogic
private Boolean isDeleted;
新版本变化

以Mybatis-Plus 3.4.2为例

不需要再配置逻辑删除插件,在application配置文件中配置以下配置即可

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

在实体类上添加@TableLogic注解的步骤不变

独立的工具模块

如果编写的配置类与业务模块不处于同一个模块中,例如以下结构:

如果要在service模块中读取到common的配置类或者工具类,首先第一步,在service模块的pom.xml中添加上common某配置类的节点坐标


    com.xxx
    service_base 
    0.0.1-SNAPSHOT

然后再在service的子模块的启动类上,添加上@ComponentScan注解启动扫描

@SpringBootApplication
@ComponentScan(basePackages = {"com.guli"})
public class EduApplication {

    public static void main(String[] args) {
        SpringApplication.run(EduApplication.class,args);
    }
}
统一返回数据格式

假设要求的返回的数据格式如下

{
    "success":布尔 // 响应的结果
    "code":数字 // 响应码
    "message":字符串 // 返回消息
    "data":HashMap // 返回数据
}

1.创建接口,定义数据返回状态码

public interface ResultCode {
    public static  Integer SUCCESS = 2000; // 成功状态码
    public static Integer ERROR = 2001; // 失败状态码
}

2.定义统一返回结果类

首先按设定定义好返回的数据格式的所有属性字段

private Boolean success;


private Integer code;


private String message;


private HashMap data = new HashMap();

然后再把构造方法私有化使该类无法new对象

private Result(){
}

之后再分别定义好成功和失败返回方法

public static Result OK(){
    Result result = new Result();
    result.setSuccess(true);
    result.setCode(ResultCode.SUCCESS);
    result.setMessage("访问成功");
    return result;
}


public static Result Error(){
    Result result = new Result();
    result.setSuccess(false);
    result.setCode(ResultCode.ERROR);
    result.setMessage("访问失败");
    return result;
}

最后使用上链式编程

public Result success(Boolean success){
    this.setSuccess(success);
    return this;
}
public Result message(String message){
    this.setMessage(message);
    return this;
}
public Result code(Integer code){
    this.setCode(code);
    return this;
}
public Result data(String key, Object value){
    this.data.put(key, value);
    return this;
}
public Result data(Map map){
    this.setData(map);
    return this;
}

链式编程可以在类调用一个方法后继续使用.再进行调用下一个方法

Mybatis-plus分页

1.以Mybatis-Plus-3.4.2版本为例,首先在Mybatis-Plus的配置类中添加分页插件

@Configuration
@MapperScan("com.xxx.xxx.mapper") // 指向Mapper层的类路径
public class EduConfig {
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false); // 该属性已被启用,但3.4.2中不会报错
    }
}

2、编写分页的Controller方法

@GetMapping("/pageList/{current}/{size}")
public Result pageTeacher(@PathVariable Integer current,@PathVariable Integer size){
    // 创建Page对象
    Page eduTeacherPage = new Page<>(current,size);
    // 调用Service层的分页方法
    teacherService.page(eduTeacherPage);
    return Result.OK().data("pageList",eduTeacherPage);
}

current参数为页码,size为查询条数

条件分页查询

service层的分页方法page有两个重载:

1.参数为Page对象的重载2.参数为Page对象和Wrapper对象的重载

第二种重载带了Mybatis-Plus的查询对象即可实现条件分页查询

使用QueryWrapper构建条件对象

@PostMapping("/pageList/search/{current}/{size}")
public Result pageTeacherListSearch(
        @PathVariable Integer current, @PathVariable Integer size,
        @RequestBody(required = false) TeacherQuery teacherQuery // TeacherQuery为条件实体类,包含名称,等级等数据属性,新建时需要添加get和set方法
) {
    System.out.println(teacherQuery);
    // 创建Page对象
    Page eduTeacherPage = new Page<>(current,size);
    // 构建条件
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.like("name",teacherQuery.getName());
    wrapper.eq("level",teacherQuery.getLevel());
    wrapper.ge("gmt_create",teacherQuery.getBegin());
    wrapper.le("gmt_create",teacherQuery.getEnd());
    // 调用Service层的分页方法
    teacherService.page(eduTeacherPage,wrapper);
    return Result.OK().data("getList",eduTeacherPage);
}
Mybatis-Plus实体类自动装填

@TableField注解标注一个属性为数据库字段,fill属性可以设置自动装填

@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;

@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;

以上面两个属性为例,FieldFill.INSERT表示新建时的装填,FieldFill.INSERT_UPDATE表示装填时装填

然后再新建一个配置类

@Component
public class MyMetObjectHandler implements metaObjectHandler {
    @Override
    public void insertFill(metaObject metaObject) {
        this.setFieldValByName("gmtCreate", new Date(), metaObject);
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    }

    @Override
    public void updateFill(metaObject metaObject) {
        this.setFieldValByName("gmtModified", new Date(), metaObject);
    }
}

这里设置的是自动装填的内容,这里的gmtCreate和gmtModified不是数据库中的字段名称,而是实体类中的属性名称

且注意,类路径要相同,否则注入无效

统一异常处理

为了处理项目运行过程中出现的某些异常,使其返回更人性化的提示给用户,这里需要用到统一异常处理

注:以下演示代码中的Result类为自定义统一返回数据格式类

全局异常

新建一个类

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    @ResponseBody // 使该方法能够返回数据
    public Result error(Exception e){
        e.printStackTrace();
        return Result.Error().message(e.getMessage());
    }

}

@ControllerAdvice学名为Controller增强器,作用是给Controller控制器添加统一的操作或者处理

@ExceptionHandler注解可以设置出现哪些异常执行被注解的方法,这里Exception.class表示所有异常都执行

以上就定义了一个全局的包含了所有的异常的处理方法

特殊异常

按照@ExceptionHandler的设定,可以指定异常并设置不同的处理方法

@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public Result error(ArithmeticException e){
    e.printStackTrace();
    return Result.Error().message("计算出错了");
}

该示例指定了一个算术异常

若有多个异常方法,例如分别定义了一个Exception异常的处理和一个ArithmeticException异常的处理,优先调用ArithmeticException的异常处理

自定义异常处理

1.创建一个自定义异常类,该类需要继承RuntimeException

@Data
@NoArgsConstructor
@AllArgsConstructor
public class GuLiException extends RuntimeException{

    private Integer code; // 状态码

    private String message; // 异常信息
    
}

2.在统一异常处理中添加使用该异常的方法

@ExceptionHandler(GuLiException.class)
@ResponseBody
public Result error(GuLiException e){
    e.printStackTrace();
    return Result.Error().code(e.getCode()).message(e.getMessage());
}

3.使自定义异常执行

由于是自定义异常,该异常不会被自动捕获,需要我们手动抛出

try {
    int i = 10 / 0;
}catch (Exception e){
    throw new GuLiException(-1,"自定义异常处理");
}
统一日志处理

在运行项目时,在控制台上打印出来信息就是日志,它可以帮助我们查看服务器的信息,运行状态,报错信息等等

日志记录器(Logger的行为是分等级的):

OFFFATALERRORWARNINFODEBUGALL 可能已失效

每种基本都会显示不同的信息,默认为INFO,如果需要更换日志级别,则需要在配置文件中添加相应的配置

logging:
  level:
    root: INFO
Logback日志工具

SpringBoot内部使用Logback作为日志实现的框架

logback相对于log4j的一些优点:https://blog.csdn.net/caisini_vc/article/details/48551287

配置Logback日志工具

首先,将配置文件中的所有的日志的配置去掉

然后在resources文件夹中创建logback-spring.xml(固定写法)

注:复制勿忘该输出文件夹名称,该属性在第10行



    
    
    
    

    logback
    
    

    
    
    
    
    
    
    
    


    
    
        
        
        
            INFO
        
        
            ${CONSOLE_LOG_PATTERN}
            
            UTF-8
        
    


    

    
    
        
        ${log.path}/log_info.log
        
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            UTF-8
        
        
        
            
            ${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
            
                100MB
            
            
            15
        
        
        
            INFO
            ACCEPT
            DENY
        
    

    
    
        
        ${log.path}/log_warn.log
        
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            UTF-8 
        
        
        
            ${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log
            
                100MB
            
            
            15
        
        
        
            warn
            ACCEPT
            DENY
        
    


    
    
        
        ${log.path}/log_error.log
        
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            UTF-8 
        
        
        
            ${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log
            
                100MB
            
            
            15
        
        
        
            ERROR
            ACCEPT
            DENY
        
    

    
    
    
    
        
        

        
        
            
            
            
            
        
    


    
    

        
            
            
            
            
            
        
    


将错误日志输出到文件

该功能需要有统一异常处理

在统一异常处理类上添加上@Slf4j注解,同时在异常处理方法中添加上日志打印语句

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) 
    @ResponseBody 
    public Result error(Exception e){
        e.printStackTrace();
        log.error(e.getMessage()); // 将异常信息打印出来
        return Result.Error().message("服务器出错啦");
    }
}

这种方式打印出来的异常信息非常简单,如果想要打印更加详细的异常日志,可以自定义一个工具类获取详细的异常信息

public class ExceptionUtil {
    public static String getMessage(Exception e) {
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            // 将出错的栈信息输出到printWriter中
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        } finally {
            if (sw != null) {
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw != null) {
                pw.close();
            }
        }
        return sw.toString();
    }
}

在统一异常处理中调用

@ExceptionHandler(Exception.class) // 指定出现哪些异常执行该方法
@ResponseBody // 使该方法能够返回数据
public Result error(Exception e){
    e.printStackTrace();
    log.error(ExceptionUtil.getMessage(e)); // 将异常打印出来
    return Result.Error().message("服务器出错啦");
}
开启跨域

配置跨域配置类

@Configuration
public class GlobalWebMvcConfigurer implements WebMvcConfigurer {

    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名进行跨域调用
        config.addAllowedOriginPattern("*");
        //允许跨越发送cookie
        config.setAllowCredentials(true);
        //放行全部原始头信息
        config.addAllowedHeader("*");
        //允许所有请求方法跨域调用
        config.addAllowedMethod("*");
        UrlbasedCorsConfigurationSource source = new UrlbasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/773469.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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