1
2
3
4
5
6
7
8
9
10
|
2.0
-api
1.0
.
1
.Final
5.0
.
1
.Final
|
http://my.oschina.net/zhaoqian/blog/89763 这个是简单的入门demo.可以先运行试试,对JAXB有个大概的使用方法.下面例子将是系统正常做的.并对并发性进行处理的一个例子.
常用的annotation有:
@XmlType
@XmlElement
@XmlRootElement
@XmlAttribute
@XmlAccessorType
@XmlAccessorOrder
@XmlTransient
@XmlJavaTypeAdapter
@Temporal(TemporalType.XXXX) -->JPA中的时间处理注解,非JAXB
@XmlElementWrapper
1.@XmlType
@XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:
同时使用了@XmlType(propOrder={})和@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)的时候,生成的xml只按照propOrder定义的顺序生成元素
@XmlType(name = "basicStruct", propOrder = {
"intValue",
"stringArray",
"stringValue"
)
在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。
2.@XmlRootElement
@XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Address {}
3.@XmlElement
@XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:
@XmlElement(name="Address")
private String yourAddress;
4.@XmlAttribute
@XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
@XmlAttribute(name="Country")
private String state;
5.@XmlAccessorType
@XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分别为:
注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。同理,如果@XmlAccessorType的访问权限为XmlAccessType.NONE,如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。
注意:虽然@XmlAccessorType为XmlAccessType.NONE,但是在java类的私有属性上加了@XmlAttribute和@XmlElement注解后,这些私有成员会映射生成xml的元素
6.@XmlAccessorOrder
@XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:
AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
XmlAccessOrder.UNDEFINED:不排序
7.@XmlTransient
@XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。
8.@XmlJavaTypeAdapter
@XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。
@XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类
XmlAdapter 抽象接口如下:
public abstract class XmlAdapter
protected XmlAdapter() {}
// Convert a value type to a bound type.
public abstract BoundType unmarshal(ValueType v);
// Convert a bound type to a value type.
public abstract ValueType marshal(BoundType v);
}
实际案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package
jaxb.shop;
import
java.util.Date;
import
java.text.SimpleDateFormat;
import
javax.xml.bind.annotation.adapters.XmlAdapter;
public
class
DateAdapter
extends
XmlAdapter
private
String pattern =
"yyyy-MM-dd HH:mm:ss"
;
SimpleDateFormat fmt =
new
SimpleDateFormat(pattern);
@Override
public
Date unmarshal(String dateStr)
throws
Exception {
return
fmt.parse(dateStr);
}
@Override
public
String marshal(Date date)
throws
Exception {
return
fmt.format(date);
}
}
//用于格式化日期在xml中的显示格式,并且由xml unmarshal为java对象时,将字符串解析为Date对象
|
在某个类中如下使用,解析出对应的时间格式.必须重载那2个方法,用于JAXB marshal xml,xml unmarshal object时候使用.
@XmlJavaTypeAdapter(value=DateAdapter.class)
private Date purDate;
9.但如果是和JPA一起使用的话,可以使用@Temporal(TemporalType.DATE)来格式时间,默认为TemporalType.TIMESTAMP类型.TemporalType属性如下:
public enum TemporalType {
DATE, //java.sql.Date
TIME, //java.sql.Time
TIMESTAMP //java.sql.Timestamp
}
java.sql.Date
日期型,精确到年月日,例如“2008-08-08”
java.sql.Time
时间型,精确到时分秒,例如“20:00:00”
java.sql.Timestamp
时间戳,精确到纳秒,例如“2008-08-08 20:00:00.000000001”
10.在JAXB标准中,@XmlElementWrapper注解表示生成一个包装 XML 表示形式的包装器元素。 此元素主要用于生成一个包装集合的包装器 XML 元素。
注:@XmlElementWrapper仅允许出现在集合属性上。最后的案例将使用这个注解.
例子XML示例.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
userinfo
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd
=
"http://www.w3.org/2001/XMLSchema"
>
<
id
>110
id
>
<
name
>Credo
name
>
<
address
>China BeiJing
address
>
<
job
>programmer
job
>
<
overinfos
>
<
overinfo
>
<
hobby
>Accompany my girlfriend.
hobby
>
<
beginDate
>2009-06-02T12:00:00
beginDate
>
<
endDate
>2109-06-02T12:00:00
endDate
>
overinfo
>
<
overinfo
>
<
hobby
>Write some code.
hobby
>
<
beginDate
>2009-06-02T12:00:00
beginDate
>
<
endDate
>2029-06-02T12:00:00
endDate
>
overinfo
>
overinfos
>
userinfo
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
package
org.credo.jaxb.model;
import
java.io.Serializable;
import
java.util.List;
import
javax.persistence.CascadeType;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.Id;
import
javax.persistence.OneToMany;
import
javax.persistence.Table;
import
javax.xml.bind.annotation.XmlAccessType;
import
javax.xml.bind.annotation.XmlAccessorType;
import
javax.xml.bind.annotation.XmlElement;
import
javax.xml.bind.annotation.XmlElementWrapper;
import
javax.xml.bind.annotation.XmlElements;
import
javax.xml.bind.annotation.XmlRootElement;
import
org.hibernate.validator.constraints.Length;
/**
* @author Credo
*/
@XmlRootElement
@XmlAccessorType
(XmlAccessType.FIELD)
@Entity
@Table
(name =
"USERINFO"
)
public
class
Userinfo
implements
Serializable{
private
static
final
long
serialVersionUID = 7870351249722416047L;
@Id
@Column
(name =
"ID"
, nullable =
false
)
private
Long id;
@Column
(name =
"NAME"
, length =
50
)
@Length
(max =
50
)
private
String name;
@Column
(name =
"ADDRESS"
, length =
50
)
@Length
(max =
50
)
private
String address;
@Column
(name =
"JOB"
, length =
50
)
@Length
(max =
50
)
private
String job;
@XmlElementWrapper
(name =
"overinfos"
)
@OneToMany
(cascade = CascadeType.ALL)
@XmlElements
(value = {
@XmlElement
(name =
"overinfo"
, type = Overinfo.
class
) })
private
List
public
Long getId() {
return
id;
}
public
void
setId(Long id) {
this
.id = id;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getAddress() {
return
address;
}
public
void
setAddress(String address) {
this
.address = address;
}
public
String getJob() {
return
job;
}
public
void
setJob(String job) {
this
.job = job;
}
public
List
return
overinfos;
}
public
void
setOverinfos(List
this
.overinfos = overinfos;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package
org.credo.jaxb.model;
import
java.io.Serializable;
import
java.util.Date;
import
javax.persistence.CascadeType;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.GenerationType;
import
javax.persistence.Id;
import
javax.persistence.JoinColumn;
import
javax.persistence.ManyToOne;
import
javax.persistence.Table;
import
javax.persistence.Temporal;
import
javax.persistence.TemporalType;
import
javax.xml.bind.annotation.XmlAccessType;
import
javax.xml.bind.annotation.XmlAccessorType;
import
javax.xml.bind.annotation.XmlTransient;
import
javax.xml.bind.annotation.XmlType;
@XmlAccessorType
(XmlAccessType.FIELD)
@XmlType
(name =
"overinfo"
)
@Entity
@Table
(name =
"OVERINFO"
)
public
class
Overinfo
implements
Serializable {
private
static
final
long
serialVersionUID = 2579971237985854291L;
@XmlTransient
@Id
@GeneratedValue
(strategy = GenerationType.IDENTITY)
@Column
(name =
"ID"
)
private
Long id;
@XmlTransient
@ManyToOne
(cascade = CascadeType.ALL)
@JoinColumn
(name =
"UserinfoId"
)
private
Userinfo userinfo;
@Column
(name =
"hobby"
, length =
20
)
private
String hobby;
@Temporal
(TemporalType.DATE)
@Column
(name =
"beginDate"
, length =
20
)
private
Date beginDate;
@Temporal
(TemporalType.DATE)
@Column
(name =
"endDate"
, length =
20
)
private
Date endDate;
public
String getHobby() {
return
hobby;
}
public
void
setHobby(String hobby) {
this
.hobby = hobby;
}
public
Date getBeginDate() {
return
beginDate;
}
public
void
setBeginDate(Date beginDate) {
this
.beginDate = beginDate;
}
public
Date getEndDate() {
return
endDate;
}
public
void
setEndDate(Date endDate) {
this
.endDate = endDate;
}
public
Long getId() {
return
id;
}
public
void
setId(Long id) {
this
.id = id;
}
public
Userinfo getUserinfo() {
return
userinfo;
}
public
void
setUserinfo(Userinfo userinfo) {
this
.userinfo = userinfo;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package
org.credo.jaxb;
import
java.util.concurrent.ConcurrentHashMap;
import
java.util.concurrent.ConcurrentMap;
import
javax.xml.bind.JAXBContext;
import
javax.xml.bind.JAXBException;
public
final
class
JAXBCache {
private
static
final
JAXBCache instance =
new
JAXBCache();
private
final
ConcurrentMap
new
ConcurrentHashMap
private
JAXBCache() {
}
public
static
JAXBCache instance() {
return
instance;
}
JAXBContext getJAXBContext(Class> clazz)
throws
JAXBException {
JAXBContext context = contextCache.get(clazz.getName());
if
( context ==
null
)
{
context = JAXBContext.newInstance(clazz);
contextCache.putIfAbsent(clazz.getName(), context);
}
return
context;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package
org.credo.jaxb;
import
java.io.File;
import
java.io.IOException;
import
javax.xml.bind.JAXBContext;
import
javax.xml.bind.SchemaOutputResolver;
import
javax.xml.transform.Result;
import
javax.xml.transform.stream.StreamResult;
import
org.credo.jaxb.model.Userinfo;
/**
* JAXB 导出Schema。
*
* @author: Credo
* @date: 2013-6-25
*/
public
class
JAXBExportSchema {
public
static
void
main(String[] args) {
JAXBContext jct;
try
{
jct = JAXBContext.newInstance(Userinfo.
class
);
jct.generateSchema(
new
Resolver());
}
catch
( Exception ex )
{
ex.printStackTrace();
}
}
}
class
Resolver
extends
SchemaOutputResolver {
@Override
public
Result createOutput(String namespaceUri, String suggestedFileName)
throws
IOException {
File file =
new
File(
"d:\\"
, suggestedFileName);
StreamResult result =
new
StreamResult(file);
result.setSystemId(file.toURI().toURL().toString());
return
result;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
package
org.credo.jaxb;
import
java.io.ByteArrayInputStream;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.util.ArrayList;
import
java.util.List;
import
javax.xml.bind.JAXBContext;
import
javax.xml.bind.JAXBException;
import
javax.xml.bind.Marshaller;
import
javax.xml.bind.Unmarshaller;
import
org.apache.commons.io.IOUtils;
import
org.credo.jaxb.model.Overinfo;
import
org.credo.jaxb.model.Userinfo;
/**
* marshal对象和unmarshal对象都是由JAXBContext创建.所以一开始需要初始化JAXBContext.
* @author Credo
*/
public
class
JAXBUtil {
/**
* 生成xml文件的二进制数据
* @param obj 对象
*/
public
static
byte
[] marshal(Object obj)
throws
JAXBException {
JAXBContext context = JAXBCache.instance().getJAXBContext(obj.getClass());
Marshaller m = context.createMarshaller();
ByteArrayOutputStream outputStream =
new
ByteArrayOutputStream();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(obj, outputStream);
byte
[] result = outputStream.toByteArray();
return
result;
}
/**
* @param data xml stream
* @param classe 类
* @return jaxb生成xml的java 类对象
*/
public
static
Object unmarshal(
byte
[] data, Class> classe)
throws
JAXBException {
JAXBContext context = JAXBCache.instance().getJAXBContext(classe);
Unmarshaller m = context.createUnmarshaller();
ByteArrayInputStream inputStream =
new
ByteArrayInputStream(data);
Object obj = m.unmarshal(inputStream);
return
obj;
}
/**
* @param data xml stream
* @param classe 类
* @return jaxb生成xml的java 类对象
*/
public
static
Object unmarshal(InputStream in, Class> classe)
throws
JAXBException, IOException {
JAXBContext context = JAXBCache.instance().getJAXBContext(classe);
byte
[] data = IOUtils.toByteArray(in);
Unmarshaller m = context.createUnmarshaller();
ByteArrayInputStream inputStream =
new
ByteArrayInputStream(data);
Object obj = m.unmarshal(inputStream);
return
obj;
}
public
static
void
main(String[] args)
throws
JAXBException {
Userinfo userinfo =
new
Userinfo();
userinfo.setId(Long.valueOf(
11
));
List
new
ArrayList
Overinfo e =
new
Overinfo();
e.setHobby(
"陪女友"
);
list.add(e);
Overinfo e1 =
new
Overinfo();
e1.setHobby(
"写代码"
);
list.add(e1);
userinfo.setOverinfos(list);
byte
[] b = JAXBUtil.marshal(userinfo);
System.out.println(
new
String(b));
userinfo = (Userinfo) JAXBUtil.unmarshal(b, Userinfo.
class
);
System.out.println(userinfo.getOverinfos().get(
0
).getHobby());
}
}
|
陪女友
下面是使用JAXBExportSchema 导出JAXB的 class的 结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
|