Quase qualquer programador Java escreveu RestController em sua vida, mas poucas pessoas se perguntam se ele faz isso corretamente. Mesmo se você é um programador experiente, você pode ter perguntas que tentarei responder. O artigo abordará estruturas como as versões 1.5 e 2.0 da bota de mola, bem como o quarkus - o recém-surgido rival da bota de primavera da red hat.

O problema
Programado por muito tempo em java e spring boot 1.5. Mas havia uma necessidade de escrever um novo projeto:
- Eu tenho json para integrar 1600 linhas, algumas classes têm 100 campos
- Eu queria experimentar Kotlin e Quarkus.
- Escreva um controlador restante que possa trabalhar com a classe de dados kotlin sem anotações e sem envolver a magia lombok. Eu quero que a classe de dados seja pequena
Você provavelmente adivinhou que a classe de dados kotlin é uma classe imutável ou imutável. Uma classe cujo construtor contém todos os campos. Eu acredito muito nesse conceito; depois de criar uma classe, ela não pode ser alterada; não há setters nela. Como a imagem da janela de encaixe não pode ser alterada no mundo, a classe de data que caiu no controlador é algo que não pode ser alterado.
Vejamos maneiras possíveis de resolver o problema, mais precisamente como em projetos modernos você pode escrever um controlador:
A opção padrão. manualmente na mola ou na bota de mola 1.5
Os controladores de descanso apareceram há muito tempo, e o exemplo a seguir é um exemplo típico de uso em java, que está em todos os tutoriais.
Nós apenas criamos o controlador mais simples
@RestController public class FruitController { @PostMapping("/fruit") public void greeting(@RequestBody Fruit request) { System.out.println(request); } }
E crie um POJO (objeto java antigo simples)
public class Fruit { public String name; public String description; public Fruit() { } public Fruit(String name, String description) { this.name = name; this.description = description; } }
pode haver variações com campos particulares e getters / setters ou anotações de lombok, mas não é o ponto.
Ótimo, criamos o primeiro controlador restante que funciona. Para 90% dos casos, a opção de trabalho. Você pode ficar aqui.
Os problemas:
O conceito imutável está quebrado.
Uma classe de dados um pouco detalhada.Podemos tornar imutáveis?
Uma reação natural a esse problema será a decisão de remover o construtor padrão e impedir a edição dos campos da classe.
@Getter public class Fruit { private String name; private String description;
Mas agora que surge um problema, verifica-se que a biblioteca (provavelmente jackson) não pode criar a classe. Provavelmente, você verá um erro como
Nenhum construtor padrão encontrado.Então, jackson
criou a classe usando o construtor sem parâmetros e depois chamou getter / setter . Que horror! Afinal, existe um construtor com todos os parâmetros? Infelizmente, porém, quando a classe é compilada, os parâmetros são mais ou menos assim.
I.e. em tempo de execução, java não sabe nada sobre nomes de parâmetros no construtor. O compilador os perde.A segunda opção é a mola ou a bota com mola 1.5 + anotações como salvação
Então, percebemos que queremos uma classe imutável e sabemos que estamos usando jackson. Então a anatotação vem em socorro.
@Getter public class Fruit { private String name; private String description; @JsonCreator public Fruit(@JsonProperty("name") String name, @JsonProperty("description")String description) { this.name = name; this.description = description; } }
No momento, em nosso projeto sobre sping boot 1.5, essas anotações estão literalmente cheias de tudo.
E se você
usar o popular gerador
jsonschema2pojo , ele gerará ainda mais anotações. Honestamente, eu não gosto deles.
Tente copiar para lá:
{ "description": "description", "name": "name" }
Na saída que obtemos (você pode apertar os olhos e folhear):
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "description", "name" }) public class Example { @JsonProperty("description") private String description; @JsonProperty("name") private String name; @JsonProperty("description") public String getDescription() { return description; } @JsonProperty("description") public void setDescription(String description) { this.description = description; } @JsonProperty("name") public String getName() { return name; } @JsonProperty("name") public void setName(String name) { this.name = name; } }
Contras: as
anotações aumentam muito a classe. Muito detalhado, para um amador.Terceira opção mola ou bota com mola 1.5 + lombok flag
Thanks
Throwable Vou citar o comentário:
“Se você usa o Lombok, a melhor maneira é escrever no lombok.config:
lombok.allArgsConstructor.addConstructorProperties = true
Isso gerará no construtor
@java.beans.ConstructorProperties
, que Jackson sabe entender. ”
Ótima opção. Ele certamente me salvaria da verbosidade das anotações.
Contras:
Mas eu quero usar o Kotlin sem lombok.
Aprendi essa opção tarde demais.A quarta versão do Spring boot 2.0
@Getter public class Fruit { private String name; private String description; public Fruit( String name, String description) { this.name = name; this.description = description; } }
Surpreendentemente, a bota de mola 2.0 funciona silenciosamente com uma classe tão imutável. E também com sua classe de dados irmão gêmeo kotlin
data class Fruit( val name : String, val description : String)
Parece que o java em tempo de execução não conhece os nomes dos parâmetros no construtor, mas por alguma razão o spring boot2 já sabe como trabalhar com a classe de dados. Então, olhe para spring-boot-starter-parent, o suporte ao Kotlin foi adicionado lá.
<plugin> <groupId>org.jetbrains.kotlin</groupId> ... <configuration> <javaParameters>true</javaParameters> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <parameters>true</parameters> </configuration> </plugin>
Eu decifrei. Para
que os nomes de parâmetro no construtor da classe não sejam perdidos durante o tempo de execução, o compilador precisa passar o sinalizador javac -parameters E o spring boot 2.0 faz isso.
Exemplo de projeto na
bota de mola 2 .
A quinta opção. Quarkus + Kotlin
Quarkus tem
um exemplo de serviço de descanso , um análogo da minha primeira opção. I.e. controlador de descanso à moda antiga. No entanto, se você quiser usá-lo com o Kotlin, precisará adicionar sinalizadores, como o boot 2 da primavera fez.
Descrição do problema
aqui . Um exemplo de como adicionar suporte à classe de dados kotlin no quarkus
aqui .
Conclusões
Você pode usar a primeira opção mais simples para criar controladores de descanso, mas eu aconselho a avançar para classes imutáveis. Escreva no Kotlin e você não precisará do lombok. O código deve ser cada vez mais fácil. Estou certo de que os criadores do Spring deliberadamente adicionaram
parâmetros javac às opções do compilador e não deve haver crime nisso. Boa sorte a todos no caminho para o código perfeito.
Obrigado a todos pela atenção!