Spring Boot 功能整合的实现
如果根据之前做的 Nest.js 后端项目功能为标准的话,那么 Spring Boot 项目需要几种功能进行整合,好在生态丰富,集成也不算困难。所以打算根据之前的项目使用 Spring Boot 重写个新的项目:
Restful API CRUD 功能实现 数据库对象关系映射功能持久化支持 OpenAPI 文档支持 参数校验判断业务 redis 缓存 ... 数据库持久化支持目前数据库持久化主要是 Spring Boot Jpa 和 Spring Boot Mybatis 。如果看过 JPA 的业务过程会发现和 Nodejs 中的 TypeORM 及其相似。Mybatis 主要可以灵活调试动态 Sql 。不管怎么说根据自己项目业务需求选定其中功能吧。
安装 MyBatis 教程可以官方文档查阅:mybatis-spring-boot-autoconfigure
Swagger 文档支持集成 Swagger UI 文档支持也非常简单,生态中的 springfox 做的不错,添加依赖:
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version></dependency>
这里需要指定版本,不指定拉取依赖会报错。
然后在启动方法添加注解:
@EnableOpenApipublic class YasuoApplication {public static void main(String[] args) { // ...}}
然后在 Controller 类上添加标识:
@Api(value = 'global', tags = '全局接口')@RestController@RequestMapping('/')public class AppController {}
在然后在方法里添加详细信息:
@Api(value = 'global', tags = '全局接口')@RestController@RequestMapping('/')public class AppController { UserService userService; @ApiOperation(value = '用户登录', notes = '系统用户登录') @PostMapping('login') public JSONObject login(@RequestParam('username') String username, @RequestParam('password') String password) {System.out.println(username);System.out.println(password);JSONObject info = new JSONObject();return info; }}
启动项目访问:http://localhost:8080/swagger-ui 即可访问。值得注意是如果你在 application 添加 server.servlet.contextPath 选项的时候记得添加对应的字段。
参数校验 JSR303从 springboot-2.3 开始,校验包被独立成了一个 starter 组件:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
比如在 DTO 类里:
package com.iiong.yasuo.dto;import lombok.Data;import javax.validation.constraints.NotEmpty;/** * Author: Jaxson * Description: 请求用户登录参数 * Date: 2021-05-26 */@Datapublic class UserLoginRequestDTO { @NotEmpty(message = '登录名称不得为空!') private String username; @NotEmpty(message = '登录密码不得为空!') private String password;}
内置的校验注解可以查看官方文档,然后进行参数校验:
@ApiOperation(value = '用户登录', notes = '系统用户登录')@PostMapping('login')public RestfulModel<UserLoginResponseDTO> login(@RequestBody @Validated UserLoginRequestDTO userLoginRequestDTO) { System.out.println(userLoginRequestDTO); UserLoginResponseDTO userLoginResponseDTO = new UserLoginResponseDTO(); userLoginResponseDTO.setId(1013401346173L); userLoginResponseDTO.setLoginName('112233'); userLoginResponseDTO.setName('系统管理员'); userLoginResponseDTO.setToken('test'); return new RestfulModel<>(0, '登录成功!', userLoginResponseDTO);}
不过默认返回的异常信息并不是很友好,需要再次简化,所以需要做个全局异常处理。如果需要可以使用 @RestControllerAdvice 注解来表示全局处理类:
/** * Author: Jaxson * Description: 全局异常处理类 * Date: 2021-05-26 */@ControllerAdvicepublic class ExceptionHandlerConfig { /** * 统一处理参数校验异常 * @param bindException 捕捉到的异常 * @return 返回数据 */ @ExceptionHandler(value = BindException.class) @ResponseBody public RestfulModel<Object> validExceptionHandler(BindException bindException) {String exceptionMsg = bindException.getBindingResult().getAllErrors().get(0).getDefaultMessage();return new RestfulModel<>(1000, exceptionMsg, null); }}
当然这里面还可以处理一些系统级别的异常,自己抛出即可。
跨域解决解决跨域问题也很简单,只需要实现接口 WebMvcConfigurer 重写方法即可:
/** * Author: Jaxson * Description: 运行跨域 * Date: 2021-05-26 */@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry corsRegistry) {corsRegistry.addMapping('/**').allowedOriginPatterns('*').allowedHeaders(CorsConfiguration.ALL).allowedMethods(CorsConfiguration.ALL).allowCredentials(true).maxAge(3600); // 1小时内不需要再预检(发OPTIONS请求) }}整合MongoDB实现文件上传下载删除
引入pom依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>
配置yml
spring: data: mongodb: host: *.*.*.* username: *** password: *** database: *** port: 27017 # 设置文件上传的大小限制 servlet: multipart: max-file-size: 10MB max-request-size: 50MB
上传下载删除
/** * @author Mr.Horse * @version 1.0 * @description: MongoDB的文件上传、下载、删除等基本操作(集合HuTool工具库) * @date 2021/4/29 9:53 */@Validated@Controller@RequestMapping('/mongo')public class MongoUploadController { private static Logger logger = LoggerFactory.getLogger(MongoUploadController.class); @Autowired private GridFsTemplate gridFsTemplate; @Autowired private MongoTemplate mongoTemplate; private static final List<String> CONTENT_TYPES = Arrays.asList('image/gif', 'image/jpeg', 'image/jpg', 'image/png'); /** * MongoDB文件上传(图片上传) * * @param file * @return */ @PostMapping('/upload') public ResponseEntity<String> fileUpload(@RequestParam('file') MultipartFile file) {try { // 校验文件信息(文件类型,文件内容) String originalFilename = file.getOriginalFilename(); if (StrUtil.isBlank(originalFilename)) {return ResponseEntity.badRequest().body('参数错误'); } String contentType = file.getContentType(); if (!CONTENT_TYPES.contains(contentType)) {return ResponseEntity.badRequest().body('文件类型错误'); } InputStream inputStream = file.getInputStream(); BufferedImage bufferedImage = ImageIO.read(inputStream); if (ObjectUtil.isEmpty(bufferedImage)) {return ResponseEntity.badRequest().body('文件内容错误'); } // 文件重命名 String suffix = FileNameUtil.getSuffix(originalFilename); String fileName = IdUtil.simpleUUID().concat('.').concat(suffix); // 文件上传,返回ObjectId ObjectId objectId = gridFsTemplate.store(inputStream, fileName, contentType); return StrUtil.isBlank(String.valueOf(objectId)) ? ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body('文件上传失败') : ResponseEntity.ok(String.valueOf(objectId));} catch (IOException e) { return ResponseEntity.badRequest().body('文件上传异常');} } /** * 根据ObjectId读取文件并写入响应流,页面进行进行相关操作,可以进行文件的下载和展示 * * @param objectId */ @GetMapping('/read') public void queryFileByObjectId(@RequestParam('objectId') @NotBlank(message = 'ObjectId不能为空') String objectId, HttpServletResponse response) {// 根据objectId查询文件GridFSFile file = gridFsTemplate.findOne(new Query(Criteria.where('_id').is(objectId)));// 创建一个文件桶GridFSBucket gridFsBucket = GridFSBuckets.create(mongoTemplate.getDb());InputStream inputStream = null;OutputStream outputStream = null;try { if (ObjectUtil.isNotNull(file)) {// 打开下载流对象GridFSDownloadStream fileStream = gridFsBucket.openDownloadStream(file.getObjectId());// 创建girdFsResource,传入下载流对象,获取流对象GridFsResource gridFsResource = new GridFsResource(file, fileStream);// 写入输出流inputStream = gridFsResource.getInputStream();outputStream = response.getOutputStream();byte[] bytes = new byte[1024];if (inputStream.read(bytes) != -1) { outputStream.write(bytes);} }} catch (IOException e) { logger.error('文件读取异常: {}', e.getMessage());} finally { IoUtil.close(outputStream); IoUtil.close(inputStream);} } /** * 根据ObjectId删除文件 * * @param objectId * @return */ @DeleteMapping('/remove') public ResponseEntity<String> removeFileByObjectId(@RequestParam('objectId') @NotBlank(message = 'ObjectId不能为空') String objectId) {gridFsTemplate.delete(new Query(Criteria.where('_id').is(objectId)));return ResponseEntity.ok('删除成功'); }}
如果需要实现在浏览器页面下载此资源的功能,可结合js进行操作(文件类型根据具体业务需求而定)。主要实现代码如下所示:
downloadNotes(noteId) { axios({url: this.BASE_API + ’/admin/mongo/file/query/’ + noteId,method: ’get’,responseType: ’arraybuffer’,params: { type: ’download’ } }).then(res => {// type类型可以设置为文本类型,这里是pdf类型const pdfUrl = window.URL.createObjectURL(new Blob([res.data], { type: `application/pdf` }))const fname = noteId // 下载文件的名字const link = document.createElement(’a’)link.href = pdfUrllink.setAttribute(’download’, fname)document.body.appendChild(link)link.click()URL.revokeObjectURL(pdfUrl) // 释放URL 对象 }) }
以上就是Spring Boot 功能整合的实现的详细内容,更多关于Spring Boot 功能整合的资料请关注好吧啦网其它相关文章!
相关文章: