Vous souhaiterez peut-être combiner le contenu d'un objet dans une chaîne de caractères et l'afficher dans un journal. À ce moment-là, je ne veux pas enregistrer ce champ! Y a-t-il quelque chose comme ça? C'est un peu ennuyeux de se donner la peine d'implémenter toString (), n'est-ce pas?
Cart.java
package jp.co.pmtech.iwata;
public class Cart {
/**ID du panier*/
private int id;
/**Articles dans le panier*/
private List<Syohin> syohinList;
//getter ou settert
}
Syohin.java
package jp.co.pmtech.iwata;
public class Syohin {
/**ID produit*/
private int id;
/**Nom du produit*/
private String name;
/**prix*/
private BigDecimal price;
//getter ou settert
}
App.java
public final class App {
public static void main(String[] args) {
Syohin syohin1 = new Syohin();
syohin1.setId(1);
syohin1.setName("Stylo à bille");
syohin1.setPrice(new BigDecimal(120));
Syohin syohin2 = new Syohin();
syohin2.setId(2);
syohin2.setName("tissu");
syohin2.setPrice(new BigDecimal(298));
List<Syohin> list = new ArrayList<>();
list.add(syohin1);
list.add(syohin2);
Cart cart = new Cart();
cart.setId(1);
cart.setSyohinList(list);
}
}
Ceci peut être réalisé en mettant en œuvre comme suit.
À propos, RecursiveToStringStyle a augmenté de commons-lang3.2, et vous pouvez l'utiliser pour le convertir récursivement en chaîne. Cependant, étant donné que ReflectionToStringBuilder est appelé en interne, le champ à générer ne peut pas être contrôlé. Par conséquent, j'ai décidé d'étendre ToStringStyle par moi-même cette fois. (Les détails de RecursiveToStringStyle seront décrits plus loin dans la partie bonus)
LogIgnore.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogIgnore {
}
Cette fois, j'essaierai de ne pas donner le prix du produit (Syohin # price).
Syohin.java
public class Syohin {
/**ID produit*/
private int id;
/**Nom du produit*/
private String name;
/**prix*/
@LogIgnore
private BigDecimal price;
}
Il semble que ReflectionToStringBuilder # accept () détermine le champ à stringifier, alors remplacez-le.
LoggingToStringBuilder.java
public class LoggingToStringBuilder extends ReflectionToStringBuilder {
public LoggingToStringBuilder(final Object object, final ToStringStyle style) {
super(object, style);
}
public static String reflectionToString(final Object object, final ToStringStyle style) {
LoggingToStringBuilder builder = new LoggingToStringBuilder(object, style) {
@Override
protected boolean accept(final Field field) {
if (!super.accept(field)) {
return false;
}
if (field.getAnnotation(LogIgnore.class) != null) {
return false;
}
return true;
}
};
return builder.toString();
}
}
Avant commons-lang3.2, il semble que vous l'ayez fait vous-même.
Créez une classe qui étend ToStringStyle en vous référant à l'article suivant. (Puisque le nom se trouve être commons-lang, je l'ai créé avec le nom de classe LoggingToStringStyle cette fois.) Sortie rétroactive avec ReflectionToString --A Memorandum
Vous pouvez copier et coller la classe, mais veuillez ne modifier que les points suivants.
LoggingToStringStyle.java
protected void appendDetail(StringBuffer buffer, String fieldName, Object value) {
for(String packaz : recursivePackags) {
if (value.getClass().getCanonicalName().startsWith(packaz)) {
// buffer.append(ToStringBuilder.reflectionToString(value, this));
//↓ Changer ici
buffer.append(LoggingToStringBuilder.reflectionToString(value, this));
return;
}
}
buffer.append(value);
}
App.config
String str = LoggingToStringBuilder.toString(cart, new LoggingToStringStyle("jp.co.pmtech.iwata"));
System.out.println(str);
résultat
jp.co.pmtech.iwata.Cart[id=1,syohinList=[jp.co.pmtech.iwata.Syohin[id=1,name=Stylo à bille],jp.co.pmtech.iwata.Syohin[id=2,name=tissu]]]
Le contenu de Cart et Syohin est correct et le prix n'est pas affiché.
Le but de cette fois est de sortir dans le journal, donc je ne me soucie pas du format de sortie. Affiche la version JSON en utilisant Jackson. Si vous ajoutez l'annotation JsonIgnore, elle ne sera pas soumise à la sérialisation JSON.
Syohin.java
public class Syohin {
/**ID produit*/
private int id;
/**Nom du produit*/
private String name;
/**prix*/
@JsonIgnore
private BigDecimal price;
}
App.java
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(cart);
System.out.println(str);
résultat
{"id":1,"syohinList":[{"id":1,"name":"Stylo à bille"},{"id":2,"name":"tissu"}]}
Je ne peux pas obtenir la valeur du prix.
Il n'y a qu'un seul problème, il semble que le contrôleur de repos de Spring Boot soit converti en JSON par Jackson. Je n'ai pas utilisé cette méthode parce que je voulais inclure le prix dans le retour de l'API. Si vous n'utilisez pas Jackson, vous pouvez utiliser cette méthode.
Comme mentionné ci-dessus, RecursiveToStringStyle a été ajouté depuis la version 3.2 de commons-lang. Faisons-le un instant. Mettez le code suivant à la fin de main et exécutez-le.
App.java
String str = ReflectionToStringBuilder.toString(cart, new RecursiveToStringStyle());
System.out.println(str);
résultat
jp.co.pmtech.iwata.Cart@610455d6[id=1,syohinList=java.util.ArrayList@2c7b84de{jp.co.pmtech.iwata.Syohin@5a07e868[id=1,name=Stylo à bille,price=java.math.BigDecimal@36baf30c[intVal=<null>,scale=0]],jp.co.pmtech.iwata.Syohin@76ed5528[id=2,name=tissu,price=java.math.BigDecimal@24d46ca6[intVal=<null>,scale=0]]}]
Il semble qu'il soit converti de manière récursive en chaîne de caractères, mais l'ID de l'objet est affiché et c'est un peu bruyant. De plus, le prix de Big Decimal n'est pas sorti ...
C'est une bonne utilisation, mais c'est peut-être juste une bûche crachée ... Pour des raisons de sécurité, vous ne voulez pas cracher d'informations personnelles et de mots de passe dans le journal. En outre, est-ce un très gros objet que vous souhaitez enregistrer? ??
Selon les exigences, JSON ou Commons-lang RecursiveToStringStyle convient. Le code source est publié sur github, veuillez donc vous y référer. https://github.com/pmt-iwata/LoggingToStringBuilder
Recommended Posts