如何用注解控制Java Map条目数?JAXB @Size注解适配问题
问题:用注解控制Java Map的条目数量
我想用注解控制Java Map的条目数量,下面的代码里@Size(max = 2)对List生效,但对Map不生效:
@XmlElement @Size(max = 2) public List<Mytype> getMytypes() { return mytypes; } @XmlElement @Size(max = 2) public Map<MyothertypeEnum, Myothertype> getMyothertypes() { return myothertypes; }
通过JAXB生成的XML Schema如下:
List对应的Schema
<xsd:element name="mytypes" type="ns0:Mytype" minOccurs="0" maxOccurs="2"/>
Map对应的Schema
<xsd:element name="myothertypes" minOccurs="0" maxOccurs="2"> <xsd:complexType> <xsd:sequence> <xsd:element name="entry" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="key" type="ns0:MyothertypeEnum" minOccurs="0"/> <xsd:element name="value" type="ns0:Myothertype" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element>
我有两个疑问:
- 怎么编写注解让
@Size作用于Map的entry元素,限制它的最大条目数? - 不理解
myothertypes元素上maxOccurs=2的含义,实际应该只允许一个Map。
解答
关于myothertypes元素的maxOccurs=2
JAXB默认会把Map直接映射为可重复的顶级元素,你加的@Size(max=2)被应用到了整个Map元素本身,而不是它的entry节点。所以maxOccurs=2表示允许出现最多2个<myothertypes>节点,这和你只需要一个Map的需求不符。要解决这个,必须给Map的getter方法添加@XmlElementWrapper注解,让JAXB生成一个单一的容器元素来包裹所有entry。
让@Size作用于Map的entry条目数
仅靠@Size无法直接让JAXB生成限制entry数量的Schema,需要结合JAXB的XML映射注解和校验注解:
修改后的代码如下:
@XmlElementWrapper(name = "myothertypes") @XmlElement(name = "entry", maxOccurs = 2) @Size(max = 2) public Map<MyothertypeEnum, Myothertype> getMyothertypes() { return myothertypes; }
效果说明:
@XmlElementWrapper(name = "myothertypes"):生成一个单一的<myothertypes>容器元素,默认maxOccurs=1,解决了之前允许多个Map的问题。@XmlElement(name = "entry", maxOccurs = 2):指定Map的每个entry对应<entry>元素,同时限制该元素最多出现2次,直接在XML Schema层面控制条目数量。@Size(max = 2):用于运行时的校验,确保Java代码中Map的实际条目数不超过2,和Schema的限制形成双重保障。
这样生成的XML Schema会变成:
<xsd:element name="myothertypes" minOccurs="0"> <xsd:complexType> <xsd:sequence> <xsd:element name="entry" minOccurs="0" maxOccurs="2"> <xsd:complexType> <xsd:sequence> <xsd:element name="key" type="ns0:MyothertypeEnum" minOccurs="0"/> <xsd:element name="value" type="ns0:Myothertype" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element>
此时<myothertypes>只能出现一次,里面的<entry>最多出现2次,完全符合你的需求。
内容的提问来源于stack exchange,提问作者shifflettd
相关产品推荐
相关产品推荐

