springboot+vue 刘老师

news2024/11/26 18:41:57

课程内容

  • 前端:vue elementui

  • 后端:springboot mybatisplus

  • 公共云部署


------boot--------

热部署

不用devtools,交给jrebel工具

+++

@RequestMapping

​ 参数

  • value 路径 method 方法
  • consumes 请求媒体类型 如 application/json
  • produces 响应媒体类型
  • params, headers 请求参数和请求头值
// localhost:8080/user?username=123&pwd=456,注意传递的是pwd,且非必须
    @GetMapping(value = "/user")
    public String Student(String username,@RequestParam(value = "pwd",required = false) String password) {
        return username + password;
    }

就是json数据


// http://localhost:8080/user2
    @PostMapping(value = "/user2")
    public String user2(@RequestBody User user) {
        System.out.println(user);
        return "post请求";
    }

VtXcmJ.png

+++

配置静态资源路径

  mvc:
    static-path-pattern: /images/**   # 地址栏路径
  web:
    resources:
      static-locations: classpath:/static/   # 本地路径

配置文件上传大小

  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

上传controller代码

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String upload(String nickname, MultipartFile photo, HttpServletRequest request) throws IOException {
        
        String path = request.getServletContext().getRealPath("/upload/");
        saveFile(photo, path);
        return "上传成功";
    }

    public void saveFile(MultipartFile photo, String path) throws IOException {
        File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(path + photo.getOriginalFilename());
        photo.transferTo(file);
    }


}

VtXmvc.png

+++

配一下本地静态资源路径,可以在浏览器访问上传的图片:

  web:
    resources:
      static-locations: /upload/

VtXB4A.png

+++

拦截器

使用:登录 监控性能 通用行为(改编码格式)

配置拦截器指定拦截路径 /user/**

@Configuration
public class WebConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/user/**");
    }
}

拦截器 true通过 false不通过

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截");
        return false;
    }
}

+++

RESTful

GET获取资源 POST新建资源 PUT更新资源 DELETE删除资源

@GetMapping @PostMapping @PutMapping @DeleteMapping

资源表现为 JSON或HTML

状态码

2xx 成功

3xx 重定向

4xx 客户端错误

5xx 服务器错误

+++

方法地址
GET/user/{id}
POST/user
PUT/user
DELETE/user/{id}
@GetMapping("/user/{id}")
    public String getUserById(@PathVariable int id) {
        return "根据id获取用户";
    }
    @PostMapping("/user")
    public String save(User user) {
        return "添加用户";
    }
    @PutMapping("/user")
    public String update(User user) {
        return "更新用户";
    }
    @DeleteMapping("/user/{id}")
    public String deleteById(@PathVariable int id) {
        return "根据ID删除用户";
    }

Swagger 2

功能:接口的调试和文档

导入依赖

配置

<!--        swagger依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

配置类

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com"))
                .paths(PathSelectors.any()).build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("演示项目API")
                .description("演示项目")
                .version("1.0")
                .build();
    }
}

MybatisPlus

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!-- 数据连接池 druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.20</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

配置数据库
boot中用xml和注解混合开发mybatis

xml方式:

yml配置

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.sbdemo1.mapper
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource
@Mapper
public interface TestMapper {
    
    List<Student> getAllStudent();
    
}

VtXXIo.png

通过小鸟直接定位到xml,注意xml配置文件位置是yml定义的,两个小鸟同名

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.sbdemo1.mapper.TestMapper">

    <select id="getAllStudent" resultType="com.example.sbdemo1.entity.Student">
        select * from student
    </select>

</mapper>

MybatisPlus 对多表无能为力,但是可以

条件查询

使用官方提供的条件包装类QueryWrapper

@Test
    void MainTest() {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "甘雨");    // 查询和甘雨同名的那一条
        mapper.selectList(queryWrapper).forEach(System.out::println);
    }

分页查询

配置分页拦截器

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }
}

@Test
    void MainTest() {
        Page<Student> studentPage = new Page<>(0, 2);
        IPage iPage = mapper.selectPage(studentPage, null);
    }

只查了前两个数据

VtXgdN.png

==>  Preparing: SELECT sid,name,sex FROM student LIMIT ?
==> Parameters: 2(Long)
<==    Columns: sid, name, sex
<==        Row: 3, 丽莎, 男
<==        Row: 7, 六月七, 女
<==      Total: 2
Closing non transactio

+++

--------Vue--------

MVVM > MVC

基本模板

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>基本用法</title>
  <script src="../vue.global.js"></script>
</head>
<body>

<!--声明被vue控制的DOM区域-->
<div id="app">{{miku}}</div>
<!--创建vue实例对象-->
<script>
  Vue.createApp({
    data() {
      return {miku: "初音"};
    }
  }).mount("#app")
</script>

</body>
</html>

组件化开发

NPM :NodeJS包管理分发工具,类似maven

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwBbC0kb-1685364834479)(null)]

vuecli脚手架搭建项目

npm install -g @vue/cli

vue create hello
Manually select features
空格去掉 Linter/Formatter
选择3
In package.json
N

直接IDEA创建工程 ~

+++

组件化开发:把代码抽象成一组物件重复使用

组件(*.vue) { template [模板(html或其他组件{组件可以互相嵌套})],script [js代码],style [样式] }

+++

组件传值:data,父组件通过prop,兄弟之间通过Vuex

+++

第三方组件

+++

element ui

导入组件cv使用即可

+++

font awesome

导入图标

+++

Axios

前端和服务器传递数据

使用XMLHttpRequests发送网络请求,自动转换JSON

+++

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IkLGXdlj-1685364834544)(null)]

+++

VtXxuV.png

+++

不常用

VtXE2d.png

+++

VtXeEb.png

配置文档

+++

后端向前端传递数据跨域错误

后端controller

@RestController
public class StudentController {
    @Resource
    TestMapper mapper;

    // http://localhost:8088/user/find
    @GetMapping(value = "/user/find")
    public List<Student> find() {
       return mapper.selectList(null);
    }

}

前端axios

created() {  //生命周期函数
        axios.get("http://localhost:8088/user/find").then(function (response) {
            console.log(response)
        })
    },
    mounted() {
        console.log("挂载App组件")
    },
    components: {
        AnimeComponent,
        HelloComponent,
    }

VtXzPq.png

跨域保证安全,浏览器遵循同源策略,同源指的是协议,主机,端口号相同

http://localhost:8080 <- 这三部分必须相同

+++

解决

在对应控制器加注解即可

@RestController
@CrossOrigin           <--  Here
public class StudentController {

+++

VtXFWz.png

HelloComponent.vue

VtXGpw.png

main.js

VtXdva.png

+++

vue router 前端路由

vue单页面基于路由和组件

+++

VueX 状态管理

管理分散的数据

+++

mockjs模拟后端生成随机数据

+++

vue-element-admin

后台前端解决方案,基于vue和elementui实现

+++

跨域认证

session 认证过程

VtXSNk.png

拓展性不好,session的跨域问题,解决方案:

  1. 把session存到redis中数据持久化

  2. 所有数据存在客户端,Token认证

+++

token [令牌] 认证

登录后,服务器产生token字符串给客户端,作为客户端访问资源的凭证

+++

jwt (token的实现)

全称JSON Web Token,发送的token字符串是 JSON对象,

VtXodL.png

+++

实现

导入依赖

<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>

生成token

private static Long expire = 604800L;
    private static String secret = "cereshuzhitingnizhenbangcereshuzhitingnizhenbang";

    public static String generateToken(String username) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + 1000 * expire);
        return Jwts.builder()
                .setHeaderParam("type", "JWT")
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }

    public static Claims getClaimsByToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

+++

封装工具方法返回信息

VtXsup.png

package com.example.sbdemo1.util;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.Map;

/**
 * --- Hello, World ---
 *
 * @author FuGuangjian
 * @version 2023/5/1 16:45
 * @desc 统一返回结果的类
 */
@Data
@Accessors(chain = true)
public class R {
    private Boolean success;
    private Integer code;
    private String message;
    private Map<String, Object> data = new HashMap<>();

    private R() {
    }
    public static R ok() {
        return new R().setSuccess(true).setCode(RCode.SUCCESS).setMessage("成功");
    }

    public static R error() {
        return new R().setSuccess(false).setCode(RCode.ERROR).setMessage("失败");
    }

    public R success(Boolean success) {
        this.setSuccess(success);
        return this;
    }

    public R message(String message) {
        this.setMessage(message);
        return this;
    }

    public R code(Integer code) {
        this.setCode(code);
        return this;
    }

    public R data(String key, Object value) {
        this.data.put(key,value);
        return this;
    }

    public R data(Map <String, Object> map) {
        this.setData(map);
        return this;
    }



}

+++

public interface RCode {
    public static Integer SUCCESS = 20000; //成功
    public static Integer ERROR = 200001;  //失败

}

+++

npm 镜像

npm install --registry=https://registry.npmmirror.com

is;
}

public R message(String message) {
    this.setMessage(message);
    return this;
}

public R code(Integer code) {
    this.setCode(code);
    return this;
}

public R data(String key, Object value) {
    this.data.put(key,value);
    return this;
}

public R data(Map <String, Object> map) {
    this.setData(map);
    return this;
}

}


+++

```java
public interface RCode {
    public static Integer SUCCESS = 20000; //成功
    public static Integer ERROR = 200001;  //失败

}

+++

npm 镜像

npm install --registry=https://registry.npmmirror.com

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

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

相关文章

DJ5-7 缓冲区管理

目录 5.7.1 缓冲的引入 5.7.2 单缓冲和双缓冲 1、单缓冲&#xff08;Single Buffer&#xff09; 2、双缓冲&#xff08;Double Buffer&#xff09; 3、双机通信时缓冲区的设置 5.7.3 循环缓冲 1、循环缓冲的组成 2、循环缓冲区的使用 3、进程同步 5.7.4 缓冲池 …

Spring Security源码剖析从入门到精通.跟学尚硅谷

1.1 概要 Spring 是非常流行和成功的 Java 应用开发框架&#xff0c;Spring Security 正是 Spring 家族中的成员。Spring Security 基于 Spring 框架&#xff0c;提供了一套 Web 应用安全性的完整解决方案。 正如你可能知道的关于安全方面的两个主要区域是“认证”和“授权”…

Mediapipe人体识别库

一、简介 官网&#xff1a;MediaPipe | Google for Developershttps://developers.google.cn/mediapipe Mediapipe 是2012年起开始公司内部使用&#xff0c;2019年google的一个开源项目&#xff0c;可以提供开源的、跨平台的常用机器学习(machine learning)方案。Mediapipe…

python-sqlite3使用指南

python下sqlite3使用指南 文章目录 python下sqlite3使用指南开发环境sqlite3常用APICRUD实例参考 开发环境 vscode ​ 开发语言&#xff1a; python vscode SQLite插件使用方法&#xff1a; 之后在这里就可以发现可视化数据&#xff1a; sqlite3常用API Python 2.5.x 以上…

信息安全实践1.3(HTTPS)

前言 做这个实验对Tomcat的版本有要求&#xff0c;最好是使用Tomcat8。因为我之前使用Tomcat10&#xff0c;然后一直做不出来。 要求 部署Web服务器端HTTPS功能&#xff0c;通过网络嗅探分析HTTPS通过SSL实施安全保护的效果 关键步骤 首先要给tomcat配置https&#xff0c;也…

设计模式之美-实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?

领域驱动设计&#xff08;Domain Driven Design&#xff0c;简称DDD&#xff09;盛行之后&#xff0c;这种基于贫血模型的传统的开发模式就更加被人诟病。而基于充血模型的DDD开发模式越来越被人提倡。所以&#xff0c;我打算用两节课的时间&#xff0c;结合一个虚拟钱包系统的…

超低功耗三通道低频无线唤醒ASK接收 125k soc芯片UM2082F08

UM2082F08 是基于单周期 8051 内核的超低功耗 8 位、、具有三通道低频无线唤醒 ASK 接收功能的 SOC 芯片。芯片可检测 30KHz~300KHz 范围的 LF&#xff08;低频&#xff09;载波频率数据并触发唤醒信号&#xff0c;同时可以调节接收灵敏度&#xff0c;确保在各种应用环境下实现…

代码随想录算法训练营15期 Day 6 | 242.有效的字母异位词 、349. 两个数组的交集 、202. 快乐数、1. 两数之和

由于昨天是周日&#xff0c;周日是休息日&#xff0c;所以就是什么也没有写啦。今天是day06天&#xff0c;继续加油。 哈希表理论基础 建议&#xff1a;大家要了解哈希表的内部实现原理&#xff0c;哈希函数&#xff0c;哈希碰撞&#xff0c;以及常见哈希表的区别&#xff0c;…

Toolkit.getDefaultToolkit()获得的java.awt.Toolkit是不是同一个? 是否为单例设计模式?答案是**是**

Toolkit.getDefaultToolkit()获得的java.awt.Toolkit是不是同一个? 是否为单例设计模式? 答案是是 反复调用Toolkit.getDefaultToolkit()获得的 java.awt.Toolkit 是同一个 import java.awt.Toolkit;public class GetDefaultToolkit是不是获得单例Toolkit {static public …

【P43】JMeter 吞吐量控制器(Throughput Controller)

文章目录 一、吞吐量控制器&#xff08;Throughput Controller&#xff09;参数说明二、测试计划设计2.1、Total Executions2.2、Percent Executions2.3、Per User 一、吞吐量控制器&#xff08;Throughput Controller&#xff09;参数说明 允许用户控制后代元素的执行的次数。…

中级软件设计师考试总结

目录 前言考前学习宏观什么是软考涉及的知识范围软考整体导图总结 微观我的分享——希尔排序学习过程结构化做题 考试阶段确定不确定 考后总结 前言 作为一名中级软件设计师&#xff0c;考试是衡量自己技能和水平的一项重要指标。在备考和考试过程中&#xff0c;我通过总结经验…

【TI毫米波雷达笔记】IWR6843AOPEVM-G的DCA1000EVM模式配置及避坑(官方手册有误)

【TI毫米波雷达笔记】IWR6843AOPEVM-G的DCA1000EVM模式配置及避坑&#xff08;官方手册有误&#xff09; IWR6843AOPEVM-G版本可以直接与DCA1000EVM连接 进行数据获取 不需要连接MMWAVEICBOOST版 直接使用 DCA1000mmWave Studio 软件进行数据采集 在官方手册中 User’s Guide…

linux环境下安装gitlab

前几天跟朋友聊天时说到gitlab版本控制。其实&#xff0c;之前也对它只是知道有这个东西&#xff0c;也会用。只是对于它的安装和配置&#xff0c;那我还是没整过。这两天&#xff0c;我找了一下网上的资料&#xff0c;还是写下吧。 一安装&#xff1a; 按网上所说&#xff0c;…

2023年上半年信息系统项目管理师下午真题及答案解析

试题一(25分) 为实现空气质量的精细化治理&#xff0c;某市规划了智慧环保项目。该项目涉及网格化监测、应急管理、执法系统等多个子系统。作为总集成商&#xff0c;A公司非常重视&#xff0c;委派李经理任项目经理&#xff0c;对公司内研发部门与项目相关的各产品线研发人员及…

带你开发一个远程控制项目---->STM32+标准库+阿里云平台+传感器模块+远程显示-------之 阿里云平台项目建造。

第一篇章&#xff1a; (13条消息) 带你开发一个远程控制项目----&#xff1e;STM32标准库阿里云平台传感器模块远程显示。_海口飞鹏岛科技有限公司的博客-CSDN博客 本次文章是指引开发者进行开发阿里云平台建造设备项目&#xff0c;可观看UP主教程&#xff0c;完成如下&#x…

今天面了一个9个月测试经验的人,开口就跟我要18K,我都愣住了....

2月初我入职了深圳某家创业公司&#xff0c;刚入职还是很兴奋的&#xff0c;到公司一看我傻了&#xff0c;公司除了我一个测试&#xff0c;公司的开发人员就只有3个前端2个后端还有2个UI&#xff0c;在粗略了解公司的业务后才发现是一个从零开始的项目&#xff0c;目前啥都没有…

测试之路,你知道这些变化吗?突破后助你走得更远...

前言 Python自动化测试&#xff1a;7天练完这60个实战项目&#xff0c;年薪过35w。 目前的面试求职市场上&#xff0c;测试领域有哪些变化&#xff1f; 以这两年软件测试发展经历来看&#xff0c;现在的求职市场&#xff0c;已经不仅仅只考察个人的项目经验和技术能力了&#…

十五、多线程(上)

文章目录 一、线程&#xff08;一&#xff09;什么是线程&#xff08;二&#xff09;Linux下的多线程&#xff08;三&#xff09;总结&#xff08;四&#xff09;线程优点&#xff08;五&#xff09;线程缺点&#xff08;六&#xff09;线程异常&#xff08;七&#xff09;线程…

字节跳动测试开发岗 3+1 面经+经验分享(收到offer,入职月薪27K)

现在&#xff0c;招聘黄金时间已经过了&#xff0c;在网上看了很多大佬的面经&#xff0c;也加了很多交流群&#xff0c;受到了很多朋友的提点&#xff0c;今天终于轮到我来分享面经啦&#xff0c;之前面试了几家公司&#xff0c;最后在八月初拿到了字节跳动测试岗的 offer&…

数据结构 -- AVL树

1、定义 平衡搜索二叉树&#xff0c;相对于搜索二叉树而言&#xff0c;AVL树又多了一个性质&#xff1a;左右子树的高度差不大于1. 2、平衡因子&#xff0c;balance factor&#xff0c;以下简称bf&#xff0c;是左子树高度减去右子树的高度 bf > 1&#xff0c;左边子树高bf …