SpringBoot+SSM项目实战 苍穹外卖(1)

目录

  • 产品原型与技术选型
  • 后端环境搭建
    • Git版本控制
    • IDEA中运行sql脚本文件
    • nginx反向代理和负载均衡
    • 完善登录功能 MD5加密 @Builder
  • 导入接口文档
  • Swagger
    • Swagger常用注解

产品原型与技术选型

管理端原型图:

在这里插入图片描述

用户端原型图:

在这里插入图片描述

餐饮企业内部员工使用。 主要功能有:

模块描述
登录/退出内部员工必须登录后,才可以访问系统管理后台
员工管理管理员可以在系统后台对员工信息进行管理,包含查询、新增、编辑、禁用等功能
分类管理主要对当前餐厅经营的 菜品分类 或 套餐分类 进行管理维护, 包含查询、新增、修改、删除等功能
菜品管理主要维护各个分类下的菜品信息,包含查询、新增、修改、删除、启售、停售等功能
套餐管理主要维护当前餐厅中的套餐信息,包含查询、新增、修改、删除、启售、停售等功能
订单管理主要维护用户在移动端下的订单信息,包含查询、取消、派送、完成,以及订单报表下载等功能
数据统计主要完成对餐厅的各类数据统计,如营业额、用户数量、订单等

移动端应用主要提供给消费者使用。主要功能有:

模块描述
登录/退出用户需要通过微信授权后登录使用小程序进行点餐
点餐-菜单在点餐界面需要展示出菜品分类/套餐分类, 并根据当前选择的分类加载其中的菜品信息, 供用户查询选择
点餐-购物车用户选中的菜品就会加入用户的购物车, 主要包含 查询购物车、加入购物车、删除购物车、清空购物车等功能
订单支付用户选完菜品/套餐后, 可以对购物车菜品进行结算支付, 这时就需要进行订单的支付
个人信息在个人中心页面中会展示当前用户的基本信息, 用户可以管理收货地址, 也可以查询历史订单数据

在这里插入图片描述

1). 用户层

本项目中在构建系统管理后台的前端页面,我们会用到H5、Vue.js、ElementUI、apache echarts(展示图表)等技术。而在构建移动端应用时,我们会使用到微信小程序。

2). 网关层

Nginx是一个服务器,主要用来作为Http服务器,部署静态资源,访问性能高。在Nginx中还有两个比较重要的作用: 反向代理和负载均衡, 在进行项目部署时,要实现Tomcat的负载均衡,就可以通过Nginx来实现。

3). 应用层

SpringBoot: 快速构建Spring项目, 采用 “约定优于配置” 的思想, 简化Spring项目的配置开发。

SpringMVC:SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合,可以无缝集成。

Spring Task: 由Spring提供的定时任务框架。

httpclient: 主要实现了对http请求的发送。

Spring Cache: 由Spring提供的数据缓存框架

JWT: 用于对应用程序上的用户进行身份验证的标记。

阿里云OSS: 对象存储服务,在项目中主要存储文件,如图片等。

Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。

POI: 封装了对Excel表格的常用操作。

WebSocket: 一种通信网络协议,使客户端和服务器之间的数据交换更加简单,用于项目的来单、催单功能实现。

4). 数据层

MySQL: 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。

Redis: 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存。

Mybatis: 本项目持久层将会使用Mybatis开发。

pagehelper: 分页插件。

spring data redis: 简化java代码操作Redis的API。

5). 工具

git: 版本控制工具, 在团队协作中, 使用该工具对项目中的代码进行管理。

maven: 项目构建工具。

junit:单元测试工具,开发人员功能实现完毕后,需要通过junit对功能进行单元测试。

postman: 接口测工具,模拟用户发起的各类HTTP请求,获取对应的响应结果。




后端环境搭建

项目初始的整体结构:

在这里插入图片描述

对工程的每个模块作用说明:

序号名称说明
1sky-take-outmaven父工程,统一管理依赖版本,聚合其他子模块
2sky-common子模块,存放公共类,例如:工具类、常量类、异常类等
3sky-pojo子模块,存放实体类、VO、DTO等
4sky-server子模块,后端服务,存放配置文件、Controller、Service、Mapper等

对项目整体结构了解后,接下来我们详细分析上述的每个子模块:

请添加图片描述

sky-common: 模块中存放的是一些公共类,可以供其他模块使用

名称说明
constant存放相关常量类
context存放上下文类
enumeration项目的枚举类存储
exception存放自定义异常类
json处理json转换的类
properties存放SpringBoot相关的配置属性类
result返回结果类的封装
utils常用工具类

请添加图片描述

sky-pojo: 模块中存放的是一些 entity、DTO、VO

名称说明
Entity实体,通常和数据库中的表对应
DTO数据传输对象,通常用于程序中各层之间传递数据
VO视图对象,为前端展示数据提供的对象
POJO普通Java对象,只有属性和对应的getter和setter

请添加图片描述

sky-server: 模块中存放的是 配置文件、配置类、拦截器、controller、service、mapper、启动类等

名称说明
config存放配置类
controller存放controller类
interceptor存放拦截器类
mapper存放mapper接口
service存放service类
SkyApplication启动类



Git版本控制

使用Git进行项目代码的版本控制,具体操作:

1). 创建Git本地仓库

请添加图片描述

请添加图片描述

当Idea中出现:

请添加图片描述

说明本地仓库创建成功。

2). 创建Github远程仓库

参考这俩篇博客:
Git的下载、安装、配置与使用
在IDEA中将项目上传至github远端仓库

关键是idea中的github用户认证,以及本地电脑的SSH keys生成与配置

3). 将本地文件推送到Git远程仓库

1.提交文件至本地仓库
忽略以下类型文件

请添加图片描述

开始提交

在这里插入图片描述

中间出现提醒:点击commit

2.添加Git远程仓库地址,这里图片以课程老师的gitee为例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.推送

在这里插入图片描述

成功推送至远程仓库




IDEA中运行sql脚本文件

课程老师提供了sql脚本以供建表,可以直接在idea里运行脚本,在idea项目中配置好数据库连接之后直接右键数据库或者表选中文件路径里的sql脚本运行就行:

请添加图片描述

每张表的说明:

序号表名中文名
1employee员工表
2category分类表
3dish菜品表
4dish_flavor菜品口味表
5setmeal套餐表
6setmeal_dish套餐菜品关系表
7user用户表
8address_book地址表
9shopping_cart购物车表
10orders订单表
11order_detail订单明细表

做完这些,启动前端代码nginx,修改后端代码application-dev.yml文件中的数据库账号和密码就可以在浏览器80端口访问页面了。

springboot项目里有两个配置文件,application.yml和application-dev.yml,这两个都是配置文件并且同时生效,因为application.yml里有这样一句:
spring:
  profiles:
   active: dev

请添加图片描述




nginx反向代理和负载均衡

登录功能测试完毕后发现前端请求地址和后端接口地址是不一致的,那是如何请求到后端服务的呢?

在这里插入图片描述

在这里插入图片描述

1). nginx反向代理

nginx 反向代理,就是将前端发送的动态请求由 nginx 转发到后端服务器。那为什么不直接通过浏览器直接请求后台服务端,需要通过nginx反向代理呢?

nginx 反向代理的好处:
提高访问速度:因为nginx本身可以进行缓存,如果访问的同一接口,并且做了数据缓存,nginx就直接可把数据返回,不需要真正地访问服务端,从而提高访问速度。


进行负载均衡:所谓负载均衡,就是把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器。


保证后端服务安全:因为一般后台服务地址不会暴露,所以使用浏览器不能直接访问,可以把nginx作为请求访问的入口,请求到达nginx后转发到具体的服务中,从而保证后端服务的安全。
在这里插入图片描述

nginx 反向代理的配置需要在nginx.conf中,如下图所示。

请添加图片描述

proxy_pass:该指令是用来设置代理服务器的地址,可以是主机名称,IP地址加端口号等形式。
如上代码的含义是:监听80端口号, 然后当我们访问 http://localhost:80/api/…/…这样的接口的时候,它会通过 location /api/ {} 这样的反向代理到 http://localhost:8080/admin/上来。

打开nginx-1.20.2\conf,打开nginx.conf:

# 反向代理,处理管理端发送的请求
location /api/ {
    proxy_pass   http://localhost:8080/admin/;
    #proxy_pass   http://webservers/admin/;
}

当在访问http://localhost/api/employee/login,nginx接收到请求后转到http://localhost:8080/admin/,故最终的请求地址为http://localhost:8080/admin/employee/login,和后台服务的访问地址一致。



2). nginx 负载均衡

当如果服务以集群的方式进行部署时,那nginx在转发请求到服务器时就需要做相应的负载均衡。其实,负载均衡从本质上来说也是基于反向代理来实现的,最终都是转发请求。

nginx 负载均衡的配置方式:

upstream webservers{ # upstream:如果代理服务器是一组服务器的话,我们可以使用upstream指令配置后端服务器组。
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}
server{
    listen 80;
    server_name localhost;

    location /api/{
        proxy_pass http://webservers/admin;#负载均衡
    }
}

如上代码的含义是:监听80端口号, 然后当我们访问 http://localhost:80/api/…/…这样的接口的时候,它会通过 location /api/ {} 这样的反向代理到 http://webservers/admin,根据webservers名称找到一组服务器,根据设置的负载均衡策略(默认是轮询)转发到具体的服务器。

注:upstream后面的名称可自定义,但要上下保持一致。

nginx 负载均衡策略:

名称说明
轮询默认方式
weight权重方式,默认为1,权重越高,被分配的客户端请求就越多
ip_hash依据ip分配方式,这样每个访客可以固定访问一个后端服务
least_conn依据最少连接方式,把请求优先分配给连接数少的后端服务
url_hash依据url分配方式,这样相同的url会被分配到同一个后端服务
fair依据响应时间方式,响应时间短的服务将会被优先分配

具体配置方式:

具体配置方式:

轮询:

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

weight:

upstream webservers{
    server 192.168.100.128:8080 weight=90;
    server 192.168.100.129:8080 weight=10;
}

ip_hash:

upstream webservers{
    ip_hash;
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

least_conn:

upstream webservers{
    least_conn;
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

url_hash:

upstream webservers{
    hash &request_uri;
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
}

fair:

upstream webservers{
    server 192.168.100.128:8080;
    server 192.168.100.129:8080;
    fair;
}



完善登录功能 MD5加密 @Builder

问题:员工表中的密码是明文存储,安全性太低。

在这里插入图片描述

解决思路:

将密码加密后存储,提高安全性
在这里插入图片描述
使用MD5加密方式对明文密码加密
在这里插入图片描述

修改数据库中明文密码,改为MD5加密后的密文:

在这里插入图片描述

修改EmployeeServiceImpl.java代码,前端提交的密码进行MD5加密后再跟数据库中密码比对:

/**
     * 员工登录
     *
     * @param employeeLoginDTO
     * @return
     */
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {

        //1、根据用户名查询数据库中的数据

        //2、处理各种异常情况(用户名不存在、密码不对、账号被锁定)
        //.......
        //密码比对
        // TODO 后期需要进行md5加密,然后再进行比对
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(employee.getPassword())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        //........

        //3、返回实体对象
        return employee;
    }

PS:在EmployeeController的login里我们新建EmployeeLoginVO对象用于返回前端时的代码是这样的:

/**
* 登录
*
* @param employeeLoginDTO
* @return
*/
@PostMapping("/login")
@ApiOperation(value = "员工登录") //描述方法的作用
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
   log.info("员工登录:{}", employeeLoginDTO);

   Employee employee = employeeService.login(employeeLoginDTO);

   //登录成功后,生成jwt令牌
   Map<String, Object> claims = new HashMap<>();
   claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
   String token = JwtUtil.createJWT(
           jwtProperties.getAdminSecretKey(),
           jwtProperties.getAdminTtl(),
           claims);

   EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
           .id(employee.getId())
           .userName(employee.getUsername())
           .name(employee.getName())
           .token(token)
           .build();

   return Result.success(employeeLoginVO);
}

其中新建EmployeeLoginVO对象时用到了builder()方法,是因为我们在EmployeeLoginVO对象定义时用到了@Builder注解:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "员工登录返回的数据格式")
public class EmployeeLoginVO implements Serializable{
	...
}

这样可以节省代码,方便我们快速构造对象。




导入接口文档

接下来,就要进入到项目的业务开发了,而我们的开发方式就是基于当前企业主流的前后端分离开发方式,那么这种方式就要求我们之前需要先将接口定义好,这样前后端人员才能并行开发,就需要将接口文档导入到管理平台,为我们后面业务开发做好准备。其实,在真实的企业开发中,接口设计过程其实是一个非常漫长的过程,可能需要多次开会讨论调整,甚至在开发的过程中才会发现某些接口定义还需要再调整,这种情况其实是非常常见的,但是由于项目时间原因,所以选择一次性导入所有的接口,在开发业务功能过程当中,也会带着大家一起来分析一下对应的接口是怎么确定下来的,为什么要这样定义。

在这里插入图片描述

将课程资料中提供的项目接口导入YApi。YApi现在官网挂了,所以使用的是Apifox。在YApi平台创建出两个项目,导入到Apifox平台。

在这里插入图片描述

请添加图片描述

请添加图片描述




Swagger

导入完接口文档之后我们就可以按照接口文档来开发后端代码了,之前我们使用postman来测试后端接口,但是有的接口可能需要的参数非常多,测试效率还是比较低的。而通过Swagger呢就可以帮助我们后端来生成接口文档,并且可以进行后端的接口测试,是后端开发非常常见的一个技术。

使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,就可以做到生成接口文档,以及在线接口调试页面。直接使用Swagger也是比较繁琐的,knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui。

knife4j的代码我们无需手撸,因为都是固定的配置型的代码,能知道起什么作用会作相应修改即可

1.pom导入 knife4j 的maven坐标

<dependency>
   <groupId>com.github.xiaoymin</groupId>
   <artifactId>knife4j-spring-boot-starter</artifactId>
   <version>3.0.2</version>
</dependency>

2.在配置类中加入 knife4j 相关配置

WebMvcConfiguration.java

/**
* 通过knife4j生成接口文档
* @return
*/
@Bean
public Docket docket() {
   ApiInfo apiInfo = new ApiInfoBuilder()
           .title("苍穹外卖项目接口文档")
           .version("2.0")
           .description("苍穹外卖项目接口文档")
           .build();
   Docket docket = new Docket(DocumentationType.SWAGGER_2)
           .apiInfo(apiInfo)
           .select()
           //指定生成接口需要扫描的包
           .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
           .paths(PathSelectors.any())
           .build();
   return docket;
}

简单看一下这个代码,加入Bean注解表示由Spring创建这个Docket对象并给IOC管理,首先创建了一个ApiInfo对象,这个其实就是在构建生成的接口文档的一系列信息,比如文档的标题、版本、描述,然后创建Docket对象,指定SWAGGER_2即Swagger版本,指定ApiInfo,指定生成接口需要扫描的包(及其子包),通过反射来解析这些类和里面的方法,最终生成接口文档。

3.设置静态资源映射,否则接口文档页面无法访问

同样还是在配置类里面 WebMvcConfiguration.java
把/doc.html和/webjars/**这些请求映射到类路径下面,即它帮我们生成接口文档之后这些文件都会放在这个路径下,所以发起请求后就需要把它映射到我们真正的这些资源上面去,

/**
 * 设置静态资源映射
 * @param registry
 */
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
//方法名addResourceHandlers不是随便写的,因为WebMvcConfiguration继承自WebMvcConfigurationSupport
//所以相当于重写方法

写好上述代码之后,重启项目进行访问测试,接口文档访问路径为 http://ip:port/doc.html —> http://localhost:8080/doc.html

在这里插入图片描述

接口测试:测试登录功能

在这里插入图片描述

思考:通过 Swagger 就可以生成接口文档,那么我们就不需要 Yapi 或者Apifox等接口管理平台了?

1、Yapi 或Apifox是设计阶段使用的工具,管理和维护接口

2、Swagger 在开发阶段使用的框架,帮助后端开发人员做后端的接口测试



Swagger常用注解

通过注解可以控制生成的接口文档,使接口文档拥有更好的可读性,常用注解如下:

注解说明
@Api用在类上,例如Controller,表示对类的说明
@ApiModel用在类上,例如entity、DTO、VO,表示对类的说明
@ApiModelProperty用在属性上,描述属性信息
@ApiOperation用在方法上,例如Controller的方法,说明方法的用途、作用

接下来,使用上述注解,生成可读性更好的接口文档,在sky-server模块中EmployeeController.java

/**
 * 员工管理
 */
@RestController
@RequestMapping("/admin/employee")
@Slf4j
@Api(tags= "员工相关接口") //描述类的作用
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 登录
     *
     * @param employeeLoginDTO
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "员工登录") //描述方法的作用
    public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
        log.info("员工登录:{}", employeeLoginDTO);

        Employee employee = employeeService.login(employeeLoginDTO);

        //登录成功后,生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

        EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
                .id(employee.getId())
                .userName(employee.getUsername())
                .name(employee.getName())
                .token(token)
                .build();

        return Result.success(employeeLoginVO);
    }

    /**
     * 退出
     *
     * @return
     */
    @PostMapping("/logout")
    @ApiOperation("员工退出") //描述方法的作用 value属性也可以不写
    public Result<String> logout() {
        return Result.success();
    }

}

在sky-pojo模块中,EmployeeLoginDTO.java

@Data
@ApiModel(description = "员工登录时传递的数据模型")
public class EmployeeLoginDTO implements Serializable {

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("密码")
    private String password;

}

EmployeeLoginVo.java

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "员工登录返回的数据格式")
public class EmployeeLoginVO implements Serializable {

    @ApiModelProperty("主键值")
    private Long id;

    @ApiModelProperty("用户名")
    private String userName;

    @ApiModelProperty("姓名")
    private String name;

    @ApiModelProperty("jwt令牌")
    private String token;

}

重启服务访问http://localhost:8080/doc.html,可以看到接口都变成了注解中的说明,接口参数也有对应描述信息。

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ClassCMS2.4漏洞复现

ClassCMS2.4漏洞复现 环境搭建 任意文件下载漏洞复现 漏洞成因 ClassCMS2.4漏洞复现 CMS源码在附件中 环境搭建 使用phpstudy2016搭建web环境&#xff0c;php版本为5.5 安装CMS 这里选择Mysql数据库进行安装 用户名和密码都写默认的admin方便记忆 输入完成后点击安装 点…

如何制作一个数字人?流程是怎样的?

​​虚拟人概念从早期动漫领域的初音未来用一首《甩葱歌》让绿色双马尾的“歌姬”形象火出圈&#xff0c;到洛天依登上央视春晚舞台&#xff0c;再到众多虚拟歌手、虚拟主播、KOL、代言人等活跃于各种情境中。 去年以来&#xff0c;元宇宙和虚拟人技术进入全球科技产业的聚光灯…

IDEA解决Git冲突详解

目录 前言&#xff1a; 何为冲突 冲突演示 IDEA冲突解决 小结&#xff1a; 前言&#xff1a; 相信大家多多少少都有了解和使用过Git&#xff0c;作为Java程序员idea可谓是无敌的存在了&#xff0c;那么如何使用idea解决Git冲突呢&#xff1f;不瞒大家前段时间在公司把同事…

怎样搭建好Google关键词广告账号结构

搭建好Google关键词广告账号结构对于实现广告效果的最大化至关重要。本文小编将为您提供一些关于如何搭建好Google关键词广告账号结构的建议和步骤。 1、设定目标和策略 在开始搭建广告账号结构之前&#xff0c;首先需要明确您的广告目标和策略。您想要增加网站流量还是提高转…

基于GAN的多尺度门合并多模态MRI图像合成

Multi-Modal MRI Image Synthesis via GAN With Multi-Scale Gate Mergence 基于GAN的多尺度门合并多模态MRI图像合成背景贡献实验方法生成器gate mergence (GM) strategy&#xff08;门控融合策略&#xff09;判别器 损失函数Thinking 基于GAN的多尺度门合并多模态MRI图像合成…

什么牌子的led台灯质量好?考研必备五款护眼台灯推荐

眼睛更是心灵的窗户&#xff0c;我们通过这扇窗来欣赏这个美好的世界。而如今&#xff0c;近视在儿童中已司空见惯&#xff0c;近视率逐年提高&#xff0c;并且低龄化的现状更加突出。据世界卫生组织的最新研究报告&#xff0c;目前中国近视患者人数多达6亿&#xff0c;其中我国…

揭秘Steam充值卡的那些坑

揭秘Steam充值卡的那些坑 steam充值卡有两种形式&#xff0c;一种是实体礼品卡图&#xff0c;即老外线下购买实体卡然后刮开卡密拍照传给买家。另一种是电子版礼品卡&#xff0c;即一串卡密&#xff0c;没有实体卡。 而实体礼品卡的可靠性肯定远高于电子版礼品卡。 相信很多人…

UIkit-UIAlertContent

简单Demo //注意&#xff01;&#xff01;&#xff01;必须放在viewController的viewDidAppear里面&#xff0c;viewDidLoad里面不行 - (void)viewDidAppear:(BOOL)animated {// 创建 UIAlertControllerUIAlertController *alertController [UIAlertController alertControll…

2023第二届全国大学生数据分析实践赛思路及代码

比赛时间 2023.12.16 09:00 至 2023.12.23 16:00 一、建模思路及代码 比赛开始后第一时间更新&#xff0c;建议先收藏哦 思路及代码更新地址 二、大赛时间 大赛报名截止时间&#xff1a;即日起—2023年12月15日 题目公布时间&#xff1a;2023年12月16日早上9点 论文提交…

SpringBoot参数校验@Validated和@Valid的使用

1、Validated和Valid区别 Validated&#xff1a;可以用在类、方法和方法参数上。但是不能用在成员属性&#xff08;字段&#xff09;上Valid&#xff1a;可以用在方法、构造函数、方法参数和成员属性&#xff08;字段&#xff09;上 2、引入依赖 Spring Boot 2.3 1 之前&…

关于SseEmitter(SSE)在本地可以响应,部署到服务器后无法响应的问题

关于SseEmitter(SSE)在本地可以响应&#xff0c;部署到服务器后无法响应的问题 GetMapping(value "/v3/detail", produces MediaType.TEXT_EVENT_STREAM_VALUE) ResponseBody public SseEmitter v3Detail(String id) {SseEmitter emitter new SseEmitter((long) …

Parasoft:正确的静态应用程序安全测试 (SAST) 解决方案

随着软件开发从Web应用扩展到工业物联网&#xff08;IIoT&#xff09;设备&#xff0c;静态应用安全测试&#xff08;SAST&#xff09;越来越有必要从根本上帮助确保软件的功能安全。根据 Forrester Research的研究&#xff0c;网络攻击是近两年安全漏洞的主要来源。因此&#…

玄学调参实践篇 | 深度学习模型 + 预训练模型 + 大模型LLM

&#x1f60d; 这篇主要简单记录一些调参实践&#xff0c;无聊时会不定期更新~ 文章目录 0、学习率与batch_size判断1、Epoch数判断2、判断模型架构是否有问题3、大模型 - 计算量、模型、和数据大小的关系4、大模型调参相关论文经验总结5、训练时模型的保存 0、学习率与batch_s…

多要素气象环境监测站知识科普

随着工业化和城市化的快速发展&#xff0c;气象环境的影响越来越受到人们的关注。为了更好地保护我们的环境&#xff0c;一款WX-CQ12 多要素气象环境监测站应运而生。这款监测站可以全方位地监测气象环境中的温度、湿度、气压、风速、风向、雨量、太阳辐射等重要要素&#xff0…

二维码看视频怎么做?轻松3 步将视频做成二维码

现在用二维码来扫码看视频是一种很流行的方式&#xff0c;这种方式只需要消耗流量就可以在线查看视频内容&#xff0c;无需等待接收或者下载视频就可以获取内容&#xff0c;有效的节省时间和空间。那么能够转换多种格式视频生成二维码的步骤是什么样的呢&#xff1f;其实想要快…

数据库范式1NF-4NF

码和属性 字段是对内而言的&#xff0c;private的 属性是对外而言的&#xff0c;public的 用Java中的类比喻就是一个对像里面定义了很多字段&#xff0c;一般情况下每个字段都有一组对应的getter&setter方法&#xff0c;注意到了吗&#xff0c;字段一般用private修饰&#…

ChatGPT生成的一些有趣的文件管理用python小程序

1. 在前位置中的所有文件夹内增加一个名为 abc 的新文件夹 import osdef create_abc_directories(root_dir.):# 获取当前目录下的所有目录subdirectories [d for d in os.listdir(root_dir) if os.path.isdir(os.path.join(root_dir, d))]# 在每个目录中创建名为abc的子目录f…

解决CentOS下PHP system命令unoconv转PDF提示“Unable to connect or start own listener“

centos系统下&#xff0c;用php的system命令unoconv把word转pdf时提示Unable to connect or start own listene的解决办法 unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1 上面这个命令在shell 终端能执行成功&#xff0c…

单词拆分 II

题目链接 单词拆分 II 题目描述 注意点 s 和 wordDict[i] 仅有小写英文字母组成wordDict 中所有字符串都 不同词典中的同一个单词可能在分段中被重复使用多次以任意顺序 返回所有这些可能的句子 解答思路 使用深度优先遍历回溯解决本题&#xff0c;每一层从idx开始遍历s&a…

如何搭建外网可访问的Serv-U FTP服务器,轻松远程共享文件!

目录 1. 前言 2. 本地FTP搭建 2.1 Serv-U下载和安装 2.2 Serv-U共享网页测试 2.3 Cpolar下载和安装 3. 本地FTP发布 3.1 Cpolar云端设置 3.2 Cpolar本地设置 4. 公网访问测试 5. 总结 1. 前言 科技日益发展的今天&#xff0c;移动电子设备似乎成了我们生活的主角&am…