Skip to content

Instantly share code, notes, and snippets.

@arganzheng
Last active December 19, 2015 23:59
Show Gist options
  • Save arganzheng/6038050 to your computer and use it in GitHub Desktop.
Save arganzheng/6038050 to your computer and use it in GitHub Desktop.
JAXB序列化
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);
}
}
}
/** 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);
}
}
}
@arganzheng
Copy link
Author

一般来说JAXBContext是static,不能也不需要每次都创建。

@arganzheng
Copy link
Author

如果不是文件对象,而是字符串那么使用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