Editor de propriedades personalizadas da primavera
1. Introdução
Simplificando, o Spring usa editores de propriedade intensamente para gerenciar a conversão entre os valoresString e os tiposObject personalizados; isso é baseado emJava Beans PropertyEditor.
Neste tutorial, examinaremos dois casos de uso diferentes para demonstrarautomatic property editor binding and custom property editor binding.
2. Vinculação do Editor de Propriedade Automática
A infraestruturaJavaBeans padrão descobrirá automaticamente as classesPropertyEditor se elas estiverem no mesmo pacote que a classe que manipulam. Além disso, eles precisam ter o mesmo nome daquela classe mais o sufixoEditor.
Por exemplo, se criarmos uma classe de modeloCreditCard, devemos nomear a classe do editorCreditCardEditor.
Vamos agora passar pora practical property binding example.
Em nosso cenário, passaremos um número de cartão de crédito como uma variável de caminho no URL de solicitação e vincularemos esse valor como objetoa CreditCard.
Vamos primeiro criar a classe de modeloCreditCard definindo os camposrawCardNumber, Número de identificação do banco (os primeiros 6 dígitos), número da conta (dígitos de 7 a 15) e código de verificação (último dígito):
public class CreditCard {
private String rawCardNumber;
private Integer bankIdNo;
private Integer accountNo;
private Integer checkCode;
// standard constructor, getters, setters
}
A seguir, criaremos a classeCreditCardEditor. Isso implementa a lógica de negócios para converter o número do cartão de crédito fornecido comoString em um objetoCreditCard.
A classe do editor de propriedade deve estenderPropertyEditorSupporte implementar os métodosgetAsText()esetAsText():
public class CreditCardEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
CreditCard creditCard = (CreditCard) getValue();
return creditCard == null ? "" : creditCard.getRawCardNumber();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.isEmpty(text)) {
setValue(null);
} else {
CreditCard creditCard = new CreditCard();
creditCard.setRawCardNumber(text);
String cardNo = text.replaceAll("-", "");
if (cardNo.length() != 16)
throw new IllegalArgumentException(
"Credit card format should be xxxx-xxxx-xxxx-xxxx");
try {
creditCard.setBankIdNo( Integer.valueOf(cardNo.substring(0, 6)) );
creditCard.setAccountNo( Integer.valueOf(
cardNo.substring(6, cardNo.length() - 1)) );
creditCard.setCheckCode( Integer.valueOf(
cardNo.substring(cardNo.length() - 1)) );
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException(nfe);
}
setValue(creditCard);
}
}
}
O métodogetAsText() é chamado ao serializar um objeto emString,, enquantosetAsText() é usado para converterString em outro objeto.
Como essas classes estão localizadas no mesmo pacote, não precisamos fazer mais nada para vincularEditor para o tipoCreditCard.
Agora podemos expor isso como um recurso em uma API REST; a operação leva um número de cartão de crédito como uma variável de caminho de solicitação e Spring vinculará esse valor de texto como um objetoCrediCard e o passará como um argumento de método:
@GetMapping(value = "/credit-card/{card-no}",
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public CreditCard parseCreditCardNumber(
@PathVariable("card-no") CreditCard creditCard) {
return creditCard;
}
Por exemplo, para um exemplo de URL de solicitação/property-editor/credit-card/1234-1234-1111-0019,, obteremos a resposta:
{
"rawCardNumber": "1234-1234-1111-0011",
"bankIdNo": 123412,
"accountNo": 341111001,
"checkCode": 9
}
3. Vinculação do editor de propriedade personalizada
Se não tivermos a classe de tipo necessária e a classe do editor de propriedade no mesmo pacote ou com as convenções de nomenclatura esperadas, teremos que definir uma ligação personalizada entre o tipo necessário e o editor de propriedade.
Em nosso cenário de vinculação do editor de propriedade customizada, um valorString será passado no URL como uma variável de caminho e vincularemos esse valor como um objetoExoticType que apenas mantém o valor como um atributo.
Como na seção 2, vamos primeiro criar uma classe de modeloExoticType:
public class ExoticType {
private String name;
// standard constructor, getters, setters
}
E nossa classe de editor de propriedade customizadaCustomExoticTypeEditor que novamente estendePropertyEditorSupport:
public class CustomExoticTypeEditor extends PropertyEditorSupport {
@Override
public String getAsText() {
ExoticType exoticType = (ExoticType) getValue();
return exoticType == null ? "" : exoticType.getName();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
ExoticType exoticType = new ExoticType();
exoticType.setName(text.toUpperCase());
setValue(exoticType);
}
}
Como o Spring não pode detectar o editor de propriedades,we’ll need a method annotated with @InitBinder in our Controller class that registers the editor:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(ExoticType.class,
new CustomExoticTypeEditor());
}
Então, podemos vincular a entrada do usuário ao objetoExoticType:
@GetMapping(
value = "/exotic-type/{value}",
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ExoticType parseExoticType(
@PathVariable("value") ExoticType exoticType) {
return exoticType;
}
Para o URL de solicitação de amostra/property-editor/exotic-type/passion-fruit, , swe obterá a resposta de amostra:
{
"name": "PASSION-FRUIT"
}
4. Conclusão
Neste artigo rápido, vimos como poderíamos usar a vinculação automática e customizada do editor de propriedade para converter valoresString legíveis por humanos em tipos Java complexos.
O código-fonte completo de nossos exemplos aqui é, como sempre,over on GitHub.