zoukankan      html  css  js  c++  java
  • 根据XML生成实体类

      因为对接系统的XML所需映射的实体类有几十个,自己来处理不太现实,于是一直找寻找这样的工具,终于让我发现了jaxb2-maven-plugin:

      http://www.mojohaus.org/jaxb2-maven-plugin/Documentation/v2.2/

      一键生成,使用也比较方便,但是需要在maven环境下,下面将介绍如果使用

      在maven工程下的pom.xml导入:

                 <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>jaxb2-maven-plugin</artifactId>
                    <version>2.5.0</version>
                    <executions>
                        <execution>
                            <id>id1</id>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>xjc</goal>
                            </goals>
                            <configuration>
                                <!-- XSD源文件 -->
                                <sources>
                                    <source>src/main/xsd</source>
                                </sources>
                                <!-- 源码输出目录 -->
                                <outputDirectory>target/generated-sources/jaxb</outputDirectory>
                                <!-- 指定文件生产 -->
                                <!--<schemaFiles>client_centric_data.xsd</schemaFiles>-->
                                <packageName>com.zgz.adsr</packageName>
                            </configuration>
                        </execution>
                    </executions>
                    <!--<configuration>-->
                        <!--&lt;!&ndash; The package of your generated sources &ndash;&gt;-->
                        <!--<packageName>com.zgz</packageName>-->
                    <!--</configuration>-->
                </plugin>

      然后,在工程中是用mvn clean install就会生成源码了。

      

      如果有多个XSD文件,可以不指定packageName,会自动分类,如果指定了,就所有实体类都在一起了,挺不方便的。可能是不清楚怎么设置,有清楚怎么设置的,麻烦评论让我学习一下。

      下面说说,映射父节点的东东,因为请求的XML父节点要设置前缀以及各种东东的,例如下图:

      

      可在生成的package-info.java文件中添加注解:

    @javax.xml.bind.annotation.XmlSchema(
         // 注意这里,下面的XmlNs匹配了,就显示ie前缀 namespace
    = "http://www.shkf.com/rootelement", //子节点的设置 //elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns={ @XmlNs(prefix="ie", namespaceURI="http://www.xxx.com/rootelement"), @XmlNs(prefix="ie1", namespaceURI="http://www.xxx.com/subaccount"), @XmlNs(prefix="ie2", namespaceURI="http://www.xxx.com/ccd"), @XmlNs(prefix="simple", namespaceURI="http://www.xxx.com/simple"), @XmlNs(prefix="tcl", namespaceURI="http://www.xxx.com/tcl"), @XmlNs(prefix="xsi", namespaceURI="http://www.w3.org/2001/XMLSchema-instance")} )

      但是schemaLocation的设置就在请求实体转换为XML的时候做设置:

      marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.xxx.com/rootelement root_elements.xsd ");

      或者在父节点实体类加个属性值:

      @XmlAttribute(name ="xsi:schemaLocation")

      public String schemaLocation="http://www.xxx.com/rootelement root_elements.xsd ";

      还有一种方式设置前缀,继承NamespacePrefixMapper,但跟着上面的属性设置,好像会有点问题,具体还没怎么研究。

      使用这方式需要引用依赖,不然会报错。

            <dependency>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-impl</artifactId>
                <version>2.2.4-1</version>
            </dependency>

      如要去掉standalone,可参考:

      https://stackoverflow.com/questions/14152523/remove-standalone-yes-from-jaxb-generated-xml

      https://blog.csdn.net/weixin_39964562/article/details/79072277

    import java.io.*;
    import javax.xml.bind.*;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.stream.*;
    
    @XmlRootElement
    public class Login {
    
        private JAXBContext jaxbContext;
        private XMLOutputFactory xmlOutputFactory;
    
        public Login() {
            try {
                jaxbContext = JAXBContext.newInstance(Login.class);
                xmlOutputFactory = XMLOutputFactory.newFactory();
            } catch(Exception e) {
                e.printStackTrace();
            }
    
        }
    
        public static void main(String[] args) {
            Login demo = new Login();
            System.out.println(demo.getMessage());
        }
    
        public final String getMessage() {
            try {
                Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
                jaxbMarshaller.setProperty("jaxb.encoding", "ISO-8859-1");
                jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
    
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                XMLStreamWriter xmlStreamWriter = xmlOutputFactory.createXMLStreamWriter(baos, (String) jaxbMarshaller.getProperty(Marshaller.JAXB_ENCODING));
                xmlStreamWriter.writeStartDocument((String) jaxbMarshaller.getProperty(Marshaller.JAXB_ENCODING), "1.0");
                jaxbMarshaller.marshal(this, xmlStreamWriter);
                xmlStreamWriter.writeEndDocument();
                xmlStreamWriter.close();
                return new String(baos.toByteArray());
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
    }

      JaxbUtil类:

    package xxxx.util;
    
    
    import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
    //import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
    import org.apache.commons.lang.StringUtils;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
    
    import javax.xml.XMLConstants;
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;
    import javax.xml.transform.Source;
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.validation.Schema;
    import javax.xml.validation.SchemaFactory;
    import javax.xml.validation.Validator;
    import java.io.IOException;
    import java.io.StringReader;
    import java.io.StringWriter;
    
    /**
     * @author GuangZe
     * @version v1.0
     * @project: vedio
     * @description: 这里描述类的用处
     * @copyright: © 2020
     * @company:
     * @date 2020/12/16 15:00
     */
    public class JaxbUtil {
    
        public static String validate(String xml, String xsdPath) {
            String errMsg = null;
            String[] xmlArr;
            int lineNum;
            try {
                Source root = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/root_elements.xsd"));
    
                Source code = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/code_lists.xsd"));
    
                Source simple = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/simple_types.xsd"));
    
                Source ccd = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/client_centric_data.xsd"));
    
                Source customer = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/customer_account.xsd"));
    
                Source sub = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/sub_account.xsd"));
    
                Source trade = new StreamSource(JaxbUtil.class.getClassLoader()
                        .getResourceAsStream("xsd/trading_account.xsd"));
    
                Source[] sourceArr = {code, simple, ccd, customer, sub, trade, root};
    
                Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(sourceArr);
                Validator validator = schema.newValidator();
                Source s = new StreamSource(new StringReader(xml));
                validator.validate(s);
            }catch (SAXParseException e){
                e.printStackTrace();
                xmlArr = xml.split("
    ");
                lineNum = e.getLineNumber();
                errMsg = e.getMessage();
                if(lineNum<=xmlArr.length && StringUtils.isNotBlank(xmlArr[lineNum-1])){
                    errMsg +="["+xmlArr[lineNum-1].trim()+"]";
                }
                System.out.println(errMsg);
            } catch (SAXException e1) {
                e1.printStackTrace();
                errMsg = e1.getMessage();
                System.out.println(errMsg);
            } catch (IOException e2) {
                e2.printStackTrace();
                errMsg = e2.getMessage();
                System.out.println(errMsg);
            }
            return errMsg;
        }
    
        /**
         * 序列化
         * @param object
         * @throws JAXBException
         */
        public static String marshall(Object object) throws JAXBException {
            // 通过映射的类创建XMLContext上下文对象,其中参数为映射的类。
            JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
            // 通过JAXBComtext上下文对象的createMarshaller()方法,创建一个对象java格式转化成XML的格式
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            //自定义前缀
    //        NamespacePrefixMapper mapper = new PreferredMapper();
    //        marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);
            marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.xxx.com/rootelement root_elements.xsd ");
            // 最后,将JAVA对象转换到制定的输出位置,其中的object为java对象。
            StringWriter writer = new StringWriter();
            marshaller.marshal(object, writer);
            return writer.toString();
        }
    
        /**
         * 解析
         * @param clazz
         * @param xml
         * @return
         * @throws Exception
         */
        public static Object unmarshaller(Class<?> clazz, String xml) throws Exception {
            if (StringUtils.isEmpty(xml)) {
                return null;
            }
            // 通过映射的类创建XMLComtext上下文对象,其中参数为映射的类。
            JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
            // 通过JAXBContext上下文对象创建createUnmarshaller()方法,创建XML转换成JAVA对象的格式。
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            // 最后,将XML转换成对映的类,转换后需要强制性转换成映射的类
            StringReader stringReader = new StringReader(xml);
            Object object = unmarshaller.unmarshal(stringReader);
            return object;
        }
    
        public static class PreferredMapper extends NamespacePrefixMapper {
            @Override
            public String getPreferredPrefix(String namespaceUri,
                                             String suggestion, boolean requirePrefix) {
                if ("http://www.xxx.com/rootelement".equals(namespaceUri)) {
                    return "ie";
                }
                return suggestion;
            }
    
        }
    
    }
  • 相关阅读:
    《Spring Boot 实战》-- 读书笔记
    Dockerfile 编写规范整理
    SQL 学习教程整理
    Spring Boot Actuator 的基本用法
    Spring Data JPA 的基本用法
    在 Spring MVC 中使用 Validation API 进行字段校验
    Spring MVC 中 Model 的用法
    windows net sc
    MySQL提示“too many connections”的解决办法
    ab命令做简单压测
  • 原文地址:https://www.cnblogs.com/zgz21/p/14150757.html
Copyright © 2011-2022 走看看