每个 Spring Boot 开发人员都应该知道的技巧

打不倒的小乖兽 2021-09-02 09:42:23 浏览数 (2643)
反馈

本篇文章,我们将讨论每个 Spring Boot 开发人员在开发程序的过程中应该要注意到的四个重要的提示。

1.使用@ModelAttribute注解

通常有部分的开发人员在请求参数会选择使用 ​Map<String, String>

@GetMapping

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

虽然它没有任何问题,但它缺少可读性。如果另一个开发人员想知道支持哪些参数,那么开发人员需要仔细阅读代码并且必须费力地找到所有参数。 此外,​Swagger 2.0​ 规范不支持 ​Map<String, String>​。

@ModelAttribute​注解可用于将请求参数映射到 Java 对象。Java 对象可以具有 API 期望的所有请求参数。这样你就可以在 java 对象上使用所有 ​javax ​验证。

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

2.使用Feign Client时,使用@Controlleradvice处理所有未处理的Feignexception

为所有 FeignException 设置一个全局异常处理程序是很好的。大多数情况下,都希望发送与底层服务发送的相同的错误响应。

样品处理

@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. 避免为集成测试而启动 Spring 应用程序上下文

对于集成测试,很多人很可能会使用 ​@SpringBootTest​ 注释测试类;此注释的问题在于它将启动整个应用程序上下文。但有时候你也可以避免它,考虑到你只是在测试服务层,而唯一需要的是 JPA 连接。

在这种情况下,可以使用​@DataJpaTest​注释来启动 ​JPA ​组件和存储库 ​bean​。并使用​@Import​ 注释加载服务类本身。

@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. 避免为每个 Spring Profile 创建多个属性文件

如果你希望你的项目中只有一个配置 (​application.yml​) 文件,那么你可以使用三个破折号分隔每个配置文件配置。

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

上面的示例中可以看到,有三个部分,它们由三个破折号分隔。第一部分是为所有弹簧配置文件启用的通用属性。第二部分用于集成测试弹簧配置文件,第三部分用于产品配置文件。


0 人点赞