最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 功能整合的實現(xiàn)

 更新時間:2021年05月27日 10:39:47   作者:Jaxson Wang  
Spring Boot生態(tài)豐富,集成也不算困難。本文簡單的介紹下功能整合的步驟,最后提供一個具體的實現(xiàn)例子,學習Spring Boot的同學可以參考下

前言

如果根據(jù)之前做的 Nest.js 后端項目功能為標準的話,那么 Spring Boot 項目需要幾種功能進行整合,好在生態(tài)豐富,集成也不算困難。所以打算根據(jù)之前的項目使用 Spring Boot 重寫個新的項目:

  • Restful API CRUD 功能實現(xiàn)
  • 數(shù)據(jù)庫對象關系映射功能持久化支持
  • OpenAPI 文檔支持
  • 參數(shù)校驗判斷業(yè)務
  • redis 緩存
  • ...

數(shù)據(jù)庫持久化支持

目前數(shù)據(jù)庫持久化主要是 Spring Boot Jpa 和 Spring Boot Mybatis 。如果看過 JPA 的業(yè)務過程會發(fā)現(xiàn)和 Nodejs 中的 TypeORM 及其相似。Mybatis 主要可以靈活調試動態(tài) Sql 。不管怎么說根據(jù)自己項目業(yè)務需求選定其中功能吧。

安裝 MyBatis 教程可以官方文檔查閱:mybatis-spring-boot-autoconfigure

Swagger 文檔支持

集成 Swagger UI 文檔支持也非常簡單,生態(tài)中的 springfox 做的不錯,添加依賴:

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-boot-starter</artifactId>
  <version>3.0.0</version>
</dependency>

這里需要指定版本,不指定拉取依賴會報錯。

然后在啟動方法添加注解:

@EnableOpenApi
public 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 = "系統(tǒng)用戶登錄")
    @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 選項的時候記得添加對應的字段。

參數(shù)校驗 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: 請求用戶登錄參數(shù)
 * Date: 2021-05-26
 */
@Data
public class UserLoginRequestDTO {
    @NotEmpty(message = "登錄名稱不得為空!")
    private String username;

    @NotEmpty(message = "登錄密碼不得為空!")
    private String password;
}

內置的校驗注解可以查看官方文檔,然后進行參數(shù)校驗:

@ApiOperation(value = "用戶登錄", notes = "系統(tǒng)用戶登錄")
@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("系統(tǒng)管理員");
    userLoginResponseDTO.setToken("test");
    return new RestfulModel<>(0, "登錄成功!", userLoginResponseDTO);
}

不過默認返回的異常信息并不是很友好,需要再次簡化,所以需要做個全局異常處理。如果需要可以使用 @RestControllerAdvice 注解來表示全局處理類:

/**
 * Author: Jaxson
 * Description: 全局異常處理類
 * Date: 2021-05-26
 */
@ControllerAdvice
public class ExceptionHandlerConfig {

    /**
     * 統(tǒng)一處理參數(shù)校驗異常
     * @param bindException 捕捉到的異常
     * @return 返回數(shù)據(jù)
     */
    @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);
    }
}

當然這里面還可以處理一些系統(tǒng)級別的異常,自己拋出即可。

跨域解決

解決跨域問題也很簡單,只需要實現(xiàn)接口 WebMvcConfigurer 重寫方法即可:

/**
 * Author: Jaxson
 * Description: 運行跨域
 * Date: 2021-05-26
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry corsRegistry) {
        corsRegistry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedHeaders(CorsConfiguration.ALL)
                .allowedMethods(CorsConfiguration.ALL)
                .allowCredentials(true)
                .maxAge(3600); // 1小時內不需要再預檢(發(fā)OPTIONS請求)
    }
}

整合MongoDB實現(xiàn)文件上傳下載刪除

引入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("參數(shù)錯誤");
            }
            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("文件上傳異常");
        }
    }


    /**
     * 根據(jù)ObjectId讀取文件并寫入響應流,頁面進行進行相關操作,可以進行文件的下載和展示
     *
     * @param objectId
     */
    @GetMapping("/read")
    public void queryFileByObjectId(@RequestParam("objectId") @NotBlank(message = "ObjectId不能為空") String objectId, HttpServletResponse response) {
        // 根據(jù)objectId查詢文件
        GridFSFile file = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(objectId)));
        // 創(chuàng)建一個文件桶
        GridFSBucket gridFsBucket = GridFSBuckets.create(mongoTemplate.getDb());
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            if (ObjectUtil.isNotNull(file)) {
                // 打開下載流對象
                GridFSDownloadStream fileStream = gridFsBucket.openDownloadStream(file.getObjectId());
                // 創(chuàng)建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);
        }
    }

    /**
     * 根據(jù)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("刪除成功");
    }

}

如果需要實現(xiàn)在瀏覽器頁面下載此資源的功能,可結合js進行操作(文件類型根據(jù)具體業(yè)務需求而定)。主要實現(xiàn)代碼如下所示:

    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 = pdfUrl
        link.setAttribute('download', fname)
        document.body.appendChild(link)
        link.click()
        URL.revokeObjectURL(pdfUrl) // 釋放URL 對象
      })
    }

以上就是Spring Boot 功能整合的實現(xiàn)的詳細內容,更多關于Spring Boot 功能整合的資料請關注腳本之家其它相關文章!

相關文章

  • springboot Interceptor攔截器excludePathPatterns忽略失效

    springboot Interceptor攔截器excludePathPatterns忽略失效

    這篇文章主要介紹了springboot Interceptor攔截器excludePathPatterns忽略失效的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • svn 清理失敗 (cleanup 失敗) 的快速解決方法

    svn 清理失敗 (cleanup 失敗) 的快速解決方法

    下面小編就為大家?guī)硪黄猻vn 清理失敗 (cleanup 失敗) 的快速解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • IDEA2020.1創(chuàng)建springboot項目(國內腳手架)安裝lombok

    IDEA2020.1創(chuàng)建springboot項目(國內腳手架)安裝lombok

    這篇文章主要介紹了IDEA2020.1創(chuàng)建springboot項目(國內腳手架)安裝lombok,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • SpringBoot中YAML配置文件實例詳解

    SpringBoot中YAML配置文件實例詳解

    前面一直在使用properties配置文件,spring boot也支持yaml配置文件,下面這篇文章主要給大家介紹了關于SpringBoot中YAML配置文件的相關資料,需要的朋友可以參考下
    2023-04-04
  • IDEA如何撤銷本地commit的代碼

    IDEA如何撤銷本地commit的代碼

    這篇文章主要介紹了IDEA如何撤銷本地commit的代碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • IDEA設置生成帶注釋的getter和setter的圖文教程

    IDEA設置生成帶注釋的getter和setter的圖文教程

    通常我們用idea默認生成的getter和setter方法是不帶注釋的,當然,我們同樣可以設置idea像MyEclipse一樣生成帶有Javadoc的模板,具體設置方法,大家參考下本文
    2018-05-05
  • JAVA實現(xiàn)社會統(tǒng)一信用代碼校驗的方法

    JAVA實現(xiàn)社會統(tǒng)一信用代碼校驗的方法

    這篇文章主要介紹了JAVA實現(xiàn)社會統(tǒng)一信用代碼校驗的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • Java中鎖的實現(xiàn)和內存語義淺析

    Java中鎖的實現(xiàn)和內存語義淺析

    這篇文章主要給大家介紹了關于Java中鎖的實現(xiàn)和內存語義的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • JAVA區(qū)間值判斷[10,20)的實現(xiàn)

    JAVA區(qū)間值判斷[10,20)的實現(xiàn)

    本文主要介紹了JAVA區(qū)間值判斷[10,20)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • Java中forEach使用lambda表達式,數(shù)組和集合的區(qū)別說明

    Java中forEach使用lambda表達式,數(shù)組和集合的區(qū)別說明

    這篇文章主要介紹了Java中forEach使用lambda表達式,數(shù)組和集合的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評論

黄梅县| 邛崃市| 林周县| 新和县| 合作市| 沙洋县| 建昌县| 黔西县| 太仓市| 南宁市| 奎屯市| 游戏| 阿城市| 淳化县| 额尔古纳市| 米脂县| 金秀| 乌审旗| 广饶县| 涡阳县| 昌乐县| 宜春市| 邵东县| 上蔡县| 龙山县| 马鞍山市| 罗山县| 将乐县| 望奎县| 佛学| 苏尼特左旗| 霸州市| 红原县| 县级市| 富顺县| 濉溪县| 洛扎县| 阳朔县| 长宁区| 澄江县| 新营市|