java - Marshall/Unmarshall 嵌套映射与 JaxB

标签 java groovy jaxb

之前有几个关于使用 JaxB 编码/取消编码 java.util.Map 的问题,其中许多问题都指向这个示例,效果很好:

http://blog.bdoughan.com/2013/03/jaxb-and-javautilmap.html

但是,如果 map 不是 @XmlRootElement 的成员,我无法让 JaxB 编码/取消编码 Map 实例。例如,这里有一个根元素类,

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static class Customer {

    private MyField myField

    MyField getMyField() {
        return myField
    }

    void setMyField(MyField myField) {
        this.myField = myField
    }

}

它的字段类的定义:

@XmlAccessorType(XmlAccessType.FIELD)
public static class MyField{

    Map<String, String> getSomeMap() {
        return someMap
    }

    void setSomeMap(Map<String, String> someMap) {
        this.someMap = someMap
    }

    @XmlElement
    private Map<String, String> someMap = new HashMap<String, String>()
}

还有一些驱动编码的代码:

    JAXBContext jc = JAXBContext.newInstance(Customer.class)

    Customer customer = new Customer()
    MyField myField1 = new MyField()
    myField1.someMap.put("foo", "bar")
    myField1.someMap.put("baz", "qux")
    customer.myField =  myField1

    Marshaller marshaller = jc.createMarshaller()
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true)
    marshaller.marshal(customer, System.out)

这个例子的结果是:

java.util.Map is an interface, and JAXB can't handle interfaces.
java.util.Map does not have a no-arg default constructor.

我正在用 Groovy 而不是 Java 编写代码,但我认为这不会有太大区别。

最佳答案

通过使用 Spring Boot 创建 @RestController 类型的 TestController,我能够使用 JAXB 遇到相同的行为。

import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping(value = "test")
class TestController {

    @RequestMapping(value = "findList")
    List findList() {
        ["Test1", "Test2", "Test3"] as ArrayList<String>
    }

    @RequestMapping(value = "findMap")
    Map findMap() {
        ["T1":"Test1", "T2":"Test2", "T3":"Test3"] as HashMap<String,String>
    }

    @RequestMapping(value = "")
    String find(){
        "Test Something"
    }
}

将 JAXB 作为 SpringBoot 中的默认实现,我可以重现/test/findList 会正确呈现 XML,但/test/findMap 会生成错误的问题,如初始帖子中所述。

对我来说,问题的解决方案是将 XML 渲染库切换到 Jackson(还有其他类似 XStream 的)。

将 Gradle 用于构建文件 (build.gradle),我只需添加 Jackson 依赖项,这与使用 Maven 时的方式非常相似:

'com.fasterxml.jackson.core:jackson-core:2.7.1', 'com.fasterxml.jackson.core:jackson-annotations:2.7.1', 'com.fasterxml.jackson.core:jackson-databind:2.7.1-1', 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.7.1', 'org.codehaus.woodstox:woodstox-core-asl:4.4.1',

关于java - Marshall/Unmarshall 嵌套映射与 JaxB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35275239/

相关文章:

java - Java中如何以不区分大小写的方式检查一个字符串是否包含另一个字符串?

java - 将文件生成到不同的包 pom.xml 中

spring - 如何在 JBoss 6 中分离耳朵类加载器和系统类加载器?

java - JAXB 类的惰性处理

java - HSQL 列名包含 #

java - JOOQ json 绑定(bind)问题

java - 如何压缩 float 据?

java - Gradle 无法压缩 .gitignore 和 .gitattributes

multithreading - Grails:将值从 Controller 传递到线程

groovy - 向 Groovy DSL 添加可选子句