SnakeYaml升级至2.2
1、修改pom.xml依赖
移除spring-boot-starter-actuator中的snakeyaml依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
添加2.2版本依赖
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.2</version>
</dependency>
2、在项目src/main/java目录下创建包
org.yaml.snakeyaml.representer
3、将下面的类复制到上面的包中
/** * Copyright (c) 2008, SnakeYAML * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.yaml.snakeyaml.representer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions.FlowStyle; import org.yaml.snakeyaml.TypeDescription; import org.yaml.snakeyaml.introspector.Property; import org.yaml.snakeyaml.introspector.PropertyUtils; import org.yaml.snakeyaml.nodes.MappingNode; import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.NodeId; import org.yaml.snakeyaml.nodes.NodeTuple; import org.yaml.snakeyaml.nodes.ScalarNode; import org.yaml.snakeyaml.nodes.SequenceNode; import org.yaml.snakeyaml.nodes.Tag; /** * Represent JavaBeans */ public class Representer extends SafeRepresenter { protected Map<Class<? extends Object>, TypeDescription> typeDefinitions = Collections.emptyMap(); //重写2.2版本 补充无参构造函数 public Representer(){ super(new DumperOptions()); this.representers.put(null,new RepresentJavaBean()); } public Representer(DumperOptions options) { super(options); this.representers.put(null, new RepresentJavaBean()); } public TypeDescription addTypeDescription(TypeDescription td) { if (Collections.EMPTY_MAP == typeDefinitions) { typeDefinitions = new HashMap<Class<? extends Object>, TypeDescription>(); } if (td.getTag() != null) { addClassTag(td.getType(), td.getTag()); } td.setPropertyUtils(getPropertyUtils()); return typeDefinitions.put(td.getType(), td); } @Override public void setPropertyUtils(PropertyUtils propertyUtils) { super.setPropertyUtils(propertyUtils); Collection<TypeDescription> tds = typeDefinitions.values(); for (TypeDescription typeDescription : tds) { typeDescription.setPropertyUtils(propertyUtils); } } protected class RepresentJavaBean implements Represent { public Node representData(Object data) { return representJavaBean(getProperties(data.getClass()), data); } } /** * Tag logic: - explicit root tag is set in serializer - if there is a predefined class tag it is * used - a global tag with class name is always used as tag. The JavaBean parent of the specified * JavaBean may set another tag (tag:yaml.org,2002:map) when the property class is the same as * runtime class * * @param properties JavaBean getters * @param javaBean instance for Node * @return Node to get serialized */ protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) { List<NodeTuple> value = new ArrayList<NodeTuple>(properties.size()); Tag tag; Tag customTag = classTags.get(javaBean.getClass()); tag = customTag != null ? customTag : new Tag(javaBean.getClass()); // flow style will be chosen by BaseRepresenter MappingNode node = new MappingNode(tag, value, FlowStyle.AUTO); representedObjects.put(javaBean, node); DumperOptions.FlowStyle bestStyle = FlowStyle.FLOW; for (Property property : properties) { Object memberValue = property.get(javaBean); Tag customPropertyTag = memberValue == null ? null : classTags.get(memberValue.getClass()); NodeTuple tuple = representJavaBeanProperty(javaBean, property, memberValue, customPropertyTag); if (tuple == null) { continue; } if (!((ScalarNode) tuple.getKeyNode()).isPlain()) { bestStyle = FlowStyle.BLOCK; } Node nodeValue = tuple.getValueNode(); if (!(nodeValue instanceof ScalarNode && ((ScalarNode) nodeValue).isPlain())) { bestStyle = FlowStyle.BLOCK; } value.add(tuple); } if (defaultFlowStyle != FlowStyle.AUTO) { node.setFlowStyle(defaultFlowStyle); } else { node.setFlowStyle(bestStyle); } return node; } /** * Represent one JavaBean property. * * @param javaBean - the instance to be represented * @param property - the property of the instance * @param propertyValue - value to be represented * @param customTag - user defined Tag * @return NodeTuple to be used in a MappingNode. Return null to skip the property */ protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { ScalarNode nodeKey = (ScalarNode) representData(property.getName()); // the first occurrence of the node must keep the tag boolean hasAlias = this.representedObjects.containsKey(propertyValue); Node nodeValue = representData(propertyValue); if (propertyValue != null && !hasAlias) { NodeId nodeId = nodeValue.getNodeId(); if (customTag == null) { if (nodeId == NodeId.scalar) { // generic Enum requires the full tag if (property.getType() != java.lang.Enum.class) { if (propertyValue instanceof Enum<?>) { nodeValue.setTag(Tag.STR); } } } else { if (nodeId == NodeId.mapping) { if (property.getType() == propertyValue.getClass()) { if (!(propertyValue instanceof Map<?, ?>)) { if (!nodeValue.getTag().equals(Tag.SET)) { nodeValue.setTag(Tag.MAP); } } } } checkGlobalTag(property, nodeValue, propertyValue); } } } return new NodeTuple(nodeKey, nodeValue); } /** * Remove redundant global tag for a type safe (generic) collection if it is the same as defined * by the JavaBean property * * @param property - JavaBean property * @param node - representation of the property * @param object - instance represented by the node */ @SuppressWarnings("unchecked") protected void checkGlobalTag(Property property, Node node, Object object) { // Skip primitive arrays. if (object.getClass().isArray() && object.getClass().getComponentType().isPrimitive()) { return; } Class<?>[] arguments = property.getActualTypeArguments(); if (arguments != null) { if (node.getNodeId() == NodeId.sequence) { // apply map tag where class is the same Class<? extends Object> t = arguments[0]; SequenceNode snode = (SequenceNode) node; Iterable<Object> memberList = Collections.emptyList(); if (object.getClass().isArray()) { memberList = Arrays.asList((Object[]) object); } else if (object instanceof Iterable<?>) { // list memberList = (Iterable<Object>) object; } Iterator<Object> iter = memberList.iterator(); if (iter.hasNext()) { for (Node childNode : snode.getValue()) { Object member = iter.next(); if (member != null) { if (t.equals(member.getClass())) { if (childNode.getNodeId() == NodeId.mapping) { childNode.setTag(Tag.MAP); } } } } } } else if (object instanceof Set) { Class<?> t = arguments[0]; MappingNode mnode = (MappingNode) node; Iterator<NodeTuple> iter = mnode.getValue().iterator(); Set<?> set = (Set<?>) object; for (Object member : set) { NodeTuple tuple = iter.next(); Node keyNode = tuple.getKeyNode(); if (t.equals(member.getClass())) { if (keyNode.getNodeId() == NodeId.mapping) { keyNode.setTag(Tag.MAP); } } } } else if (object instanceof Map) { // NodeId.mapping ends-up here Class<?> keyType = arguments[0]; Class<?> valueType = arguments[1]; MappingNode mnode = (MappingNode) node; for (NodeTuple tuple : mnode.getValue()) { resetTag(keyType, tuple.getKeyNode()); resetTag(valueType, tuple.getValueNode()); } } else { // the type for collection entries cannot be // detected } } } private void resetTag(Class<? extends Object> type, Node node) { Tag tag = node.getTag(); if (tag.matches(type)) { if (Enum.class.isAssignableFrom(type)) { node.setTag(Tag.STR); } else { node.setTag(Tag.MAP); } } } /** * Get JavaBean properties to be serialised. The order is respected. This method may be overridden * to provide custom property selection or order. * * @param type - JavaBean to inspect the properties * @return properties to serialise */ protected Set<Property> getProperties(Class<? extends Object> type) { if (typeDefinitions.containsKey(type)) { return typeDefinitions.get(type).getProperties(); } return getPropertyUtils().getProperties(type); } }

浙公网安备 33010602011771号