Last active
December 19, 2015 23:59
-
-
Save arganzheng/6038050 to your computer and use it in GitHub Desktop.
JAXB序列化
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.arganzheng.study.metadata.dao; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.io.Reader; | |
import java.util.List; | |
import javax.xml.bind.JAXBContext; | |
import javax.xml.bind.Marshaller; | |
import javax.xml.bind.Unmarshaller; | |
import org.apache.commons.io.output.FileWriterWithEncoding; | |
import org.apache.log4j.Logger; | |
import me.arganzheng.study.metadata.model.Api; | |
import me.arganzheng.study.metadata.model.ApiMetadata; | |
import me.arganzheng.study.metadata.model.Module; | |
import me.arganzheng.study.metadata.model.Param; | |
import me.arganzheng.study.metadata.model.Request; | |
import me.arganzheng.study.metadata.model.Response; | |
public class XmlFileApiMetadataDao implements ApiMetadataDao { | |
private final static Logger log = Logger.getLogger(XmlFileApiMetadataDao.class); | |
private final static JAXBContext JAXB_CONTEXT; | |
static { | |
try { | |
JAXB_CONTEXT = JAXBContext.newInstance(ApiMetadata.class, Module.class, Api.class, Request.class, | |
Response.class, Param.class); | |
} catch (Exception ex) { | |
throw new RuntimeException("初始化JAXBContext失败!", ex); | |
} | |
} | |
private static final String DEFAULT_RESOURCE_PATH = "/META-INF/api_metadata.xml"; | |
private static final String FILE_PATH_PROPERTY = "ApiMetadataXmlFile"; | |
private static final String DEFAULT_FILE_PATH = "/data/tomcatlog/api/metadata/api_metadata.xml"; | |
private static final String FILE_PATH; | |
static { | |
String prop = System.getProperty(FILE_PATH_PROPERTY); | |
String env = System.getenv(FILE_PATH_PROPERTY); | |
FILE_PATH = prop != null ? prop : env != null ? env : DEFAULT_FILE_PATH; | |
} | |
private final static File FILE = new File(FILE_PATH); | |
private static final String ENCODING = "UTF-8"; | |
private long lastModified = 0L; | |
private ApiMetadata apiMetadata; | |
public XmlFileApiMetadataDao(){ | |
checkUpdate(); | |
} | |
private void checkUpdate() { | |
if (apiMetadata == null || FILE.lastModified() > lastModified) { | |
synchronized (this) { | |
if (apiMetadata == null || FILE.lastModified() > lastModified) { | |
try { | |
InputStream updateInputStream = null; | |
if (FILE.lastModified() > lastModified) { | |
log.info("Reload API metadata from " + FILE + "..."); | |
updateInputStream = new FileInputStream(FILE); | |
} else if (apiMetadata == null) { | |
log.info("Reload API metadata from classpath..."); | |
updateInputStream = XmlFileApiMetadataDao.class.getResourceAsStream(DEFAULT_RESOURCE_PATH); | |
} | |
Reader store = new InputStreamReader(updateInputStream, ENCODING); | |
Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller(); | |
apiMetadata = (ApiMetadata) unmarshaller.unmarshal(store); | |
store.close(); | |
lastModified = FILE.lastModified(); | |
} catch (Exception ex) { | |
throw new RuntimeException("接口元数据文件解析错误!", ex); | |
} | |
} | |
} | |
} | |
} | |
public ApiMetadata getApiMetadata() { | |
checkUpdate(); | |
return apiMetadata; | |
} | |
@Override | |
public List<Module> listModule() { | |
checkUpdate(); | |
return apiMetadata.getModules(); | |
} | |
@Override | |
public Module getModule(String moduleName) { | |
checkUpdate(); | |
return apiMetadata.getModulesByName().get(moduleName); | |
} | |
@Override | |
public List<Api> listApi(String moduleName) { | |
Module module = getModule(moduleName); | |
return module == null ? null : module.getApiList(); | |
} | |
@Override | |
public Api getApi(String moduleName, String apiName) { | |
Module module = getModule(moduleName); | |
return module == null ? null : module.getApiMap().get(apiName); | |
} | |
@Override | |
public void saveAsSource(ApiMetadata metadata) { | |
try { | |
String path = "metadata/api_metadata.xml"; | |
Marshaller marshaller = JAXB_CONTEXT.createMarshaller(); | |
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); | |
marshaller.setProperty(Marshaller.JAXB_ENCODING, ENCODING); | |
marshaller.marshal(metadata, new FileWriterWithEncoding(path, ENCODING)); | |
} catch (Exception ex) { | |
throw new RuntimeException("接口元数据文件写入失败!", ex); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Class which un/marshals objects to XML */ | |
public class XmlFormatter { | |
private static Marshaller marshaller = null; | |
private static Unmarshaller unmarshaller = null; | |
static { | |
try { | |
JAXBContext context = JAXBContext.newInstance("path.to.package"); | |
marshaller = context.createMarshaller(); | |
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); | |
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); | |
unmarshaller = context.createUnmarshaller(); | |
} catch (JAXBException e) { | |
throw new RuntimeException("There was a problem creating a JAXBContext object for formatting the object to XML."); | |
} | |
} | |
public void marshal(Marshalable obj, OutputStream os) throws XMLMarshalException { | |
try { | |
marshaller.marshal(obj, os); | |
} catch (JAXBException jaxbe) { | |
throw new XMLMarshalException(jaxbe); | |
} | |
} | |
public String marshalToString(Marshalable obj) throws XMLMarshalException { | |
try { | |
StringWriter sw = new StringWriter(); | |
return marshaller.marshal(obj, sw); | |
} catch (JAXBException jaxbe) { | |
throw new XMLMarshalException(jaxbe); | |
} | |
} | |
} |
如果不是文件对象,而是字符串那么使用StringWrite和StringReader做相应的适配:
public static String convertToXML(Service service) {
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_ENCODING, ENCODING);
StringWriter sw = new StringWriter();
marshaller.marshal(service, sw);
return sw.toString();
} catch (JAXBException e) {
throw new RuntimeException("marshaller idl metadata failed!", e);
}
}
public static Service convertToService(String xmlContent) {
try {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(xmlContent);
Service service = (Service) unmarshaller.unmarshal(reader);
return service;
} catch (JAXBException e) {
throw new RuntimeException("unmarshaller idl metadata failed!", e);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
一般来说
JAXBContext
是static,不能也不需要每次都创建。