App下載

每個(gè) Spring Boot 開(kāi)發(fā)人員都應(yīng)該知道的技巧

打不倒的小乖獸 2021-09-02 09:42:23 瀏覽數(shù) (2293)
反饋

本篇文章,我們將討論每個(gè) Spring Boot 開(kāi)發(fā)人員在開(kāi)發(fā)程序的過(guò)程中應(yīng)該要注意到的四個(gè)重要的提示。

1.使用@ModelAttribute注解

通常有部分的開(kāi)發(fā)人員在請(qǐng)求參數(shù)會(huì)選擇使用 ?Map<String, String>?

@GetMapping

public SomeDto getAll(@RequestParam Map<String, String> params)

雖然它沒(méi)有任何問(wèn)題,但它缺少可讀性。如果另一個(gè)開(kāi)發(fā)人員想知道支持哪些參數(shù),那么開(kāi)發(fā)人員需要仔細(xì)閱讀代碼并且必須費(fèi)力地找到所有參數(shù)。 此外,?Swagger 2.0? 規(guī)范不支持 ?Map<String, String>?。

?@ModelAttribute?注解可用于將請(qǐng)求參數(shù)映射到 Java 對(duì)象。Java 對(duì)象可以具有 API 期望的所有請(qǐng)求參數(shù)。這樣你就可以在 java 對(duì)象上使用所有 ?javax ?驗(yàn)證。

@GetMapping
public SomeDto getAll(@Valid @ModelAttribute SomeObject params)

2.使用Feign Client時(shí),使用@Controlleradvice處理所有未處理的Feignexception

為所有 FeignException 設(shè)置一個(gè)全局異常處理程序是很好的。大多數(shù)情況下,都希望發(fā)送與底層服務(wù)發(fā)送的相同的錯(cuò)誤響應(yīng)。

樣品處理

@RequiredArgsConstructor
@ControllerAdvice
public class ExceptionControllerAdvice {
private final ObjectMapper mapper;

@ExceptionHandler(FeignException.class)
public final ResponseEntity < String > handleFeignException(FeignException fex) {
        log.error("Exception from downstream service call - ", fex);
        HttpStatus status = Optional.ofNullable(HttpStatus.resolve(fex.status()))
            .orElse(HttpStatus.INTERNAL_SERVER_ERROR);
        String body = Strings.isNullOrEmpty(fex.contentUTF8()) ? fex.getMessage() : fex.contentUTF();
        return new ResponseEntity < > (
            body,
            getHeadersWithContentType(body),
            status
        );
    }
private MultiValueMap < String, String > getHeadersWithContentType(String body) {
        HttpHeaders headers = new HttpHeaders();
        String contentType = isValidJSON(body) ? "application/json" : "text/plain";
        headers.add(HttpHeaders.CONTENT_TYPE, contentType);
        return headers;
    }
private boolean isValidJSON(String body) {
        try {
            if (Strings.isNullOrEmpty(body)) return false;
            mapper.readTree(body);
            return true;
        } catch (JacksonException e) {
            return false;
        }
    }
}

3. 避免為集成測(cè)試而啟動(dòng) Spring 應(yīng)用程序上下文

對(duì)于集成測(cè)試,很多人很可能會(huì)使用 ?@SpringBootTest? 注釋測(cè)試類;此注釋的問(wèn)題在于它將啟動(dòng)整個(gè)應(yīng)用程序上下文。但有時(shí)候你也可以避免它,考慮到你只是在測(cè)試服務(wù)層,而唯一需要的是 JPA 連接。

在這種情況下,可以使用?@DataJpaTest?注釋來(lái)啟動(dòng) ?JPA ?組件和存儲(chǔ)庫(kù) ?bean?。并使用?@Import? 注釋加載服務(wù)類本身。

@DataJpaTest(showSql = false)
@Import(TestService.class)
public class ServiceTest {
    @Autowired
    private TestService service;
    
    @Test
    void testFindAll() {
        List<String> values = service.findAll();
        assertEquals(1, values.size());
    }
}

4. 避免為每個(gè) Spring Profile 創(chuàng)建多個(gè)屬性文件

如果你希望你的項(xiàng)目中只有一個(gè)配置 (?application.yml?) 文件,那么你可以使用三個(gè)破折號(hào)分隔每個(gè)配置文件配置。

api.info:
  title: rest-serice
  description: some description
  version: 1.0client.url: http://dev.server
---
spring.config.activate.on-profile: integration-test
client.url: http://mock-server
---
spring.config.activate.on-profile: prod
client.url: http://real-server

上面的示例中可以看到,有三個(gè)部分,它們由三個(gè)破折號(hào)分隔。第一部分是為所有彈簧配置文件啟用的通用屬性。第二部分用于集成測(cè)試彈簧配置文件,第三部分用于產(chǎn)品配置文件。


0 人點(diǎn)贊