Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.4k views
in Technique[技术] by (71.8m points)

xstream转换xml时出错

我的xml是这样的

`<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE>

<HEADER>
    <MESSAGENAME>CheckRequest</MESSAGENAME>
    <TRANSACTIONID>20201120110748404</TRANSACTIONID>
    <REPLYSUBJECTNAME>PROD.Listen.DRYT1200</REPLYSUBJECTNAME>
    <INBOXNAME />
    <LISTENER>PEMListener</LISTENER>
</HEADER>

? <BODY>
? <LINENAME>DRYT0100</LINENAME>
? <LINE_RECIPE_LIST>
? <LINE_RECIPE>
? <RECIPEEVENTTYPE>Check</RECIPEEVENTTYPE>
? <LINERECIPENAME>E495A1A2400A1</LINERECIPENAME>
? <TIMEOUT_UNIT_LIST />
? <CIMOFF_UNIT_LIST />
? <UNIT_LIST>
? <UNITNAME>DRYT0141</UNITNAME>
? <UNITRECIPENAME>11</UNITRECIPENAME>
? <RECIPEPARALIST>
? <PARA>
? <TRACELEVEL>M</TRACELEVEL>
? <PARANAME>Recipe_Version</PARANAME>
? <VALUETYPE>NUMBER</VALUETYPE>
? <PARAVALUE>57.5A1B_NP_ETCH</PARAVALUE>
? </PARA>
? <PARA>
? <TRACELEVEL>M</TRACELEVEL>
? <PARANAME>LINE RECIPEID</PARANAME>
? <VALUETYPE>NUMBER</VALUETYPE>
? <PARAVALUE>0310</PARAVALUE>
? </PARA>
? </RECIPEPARALIST>
? </UNIT_LIST>
? </LINE_RECIPE>
? </LINE_RECIPE_LIST>
? <OPERATORID />
? <TRANSACTIONSTARTTIME>2020-11-20 11:07:49.107</TRANSACTIONSTARTTIME>
? </BODY>
</MESSAGE>`

我的class是这样的:

``

package com.example.rvxmldemo.testmdoel;


import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

import java.util.ArrayList;
import java.util.List;

@XStreamAlias("MESSAGE")
public class Message {
    @XStreamAlias("HEADER")
    @XStreamAsAttribute
    Header header;

    @XStreamAlias("BODY")
    @XStreamAsAttribute
    Body body;

    @XStreamAlias("RETURN")
    @XStreamAsAttribute
    Header.ReturnMessage Return;

    public Message() {
    }


    public Header getHeader() {
        return header;
    }

    public void setHeader(Header header) {
        this.header = header;
    }

    public Header.ReturnMessage getReturn() {
        return Return;
    }

    public void setReturn(Header.ReturnMessage aReturn) {
        Return = aReturn;
    }

    public Body getBody() {
        return body;
    }

    public void setBody(Body body) {
        this.body = body;
    }

    @XStreamAlias("HEADER")
    public class Header {
        @XStreamAlias("MESSAGENAME")
        @XStreamAsAttribute
        String messageName;

        @XStreamAlias("TRANSACTIONID")
        @XStreamAsAttribute
        String transactionID;

        @XStreamAlias("REPLYSUBJECTNAME")
        @XStreamAsAttribute
        String replySubjectName;

        @XStreamAlias("INBOXNAME")
        @XStreamAsAttribute
        String inboxName;

        @XStreamAlias("LISTENER")
        @XStreamAsAttribute
        String listener;

        public Header() {
        }


        @XStreamAlias("RETURN")
        public class ReturnMessage {
            @XStreamAlias("RETURNCODE")
            String returnCode;
            @XStreamAlias("RETURNMESSAGE")
            String returnMessage;

            public ReturnMessage() {
            }

            public String getReturnCode() {
                return returnCode;
            }

            public void setReturnCode(String returnCode) {
                this.returnCode = returnCode;
            }

            public String getReturnMessage() {
                return returnMessage;
            }

            public void setReturnMessage(String returnMessage) {
                this.returnMessage = returnMessage;
            }
        }

    }


    @XStreamAlias("BODY")
    public class Body {

        @XStreamAlias("LINENAME")
        @XStreamAsAttribute
        String lineName;

        @XStreamAlias("LINE_RECIPE_LIST")
        @XStreamImplicit(itemFieldName = "LINE_RECIPE")
        List<LineRecipe> LINE_RECIPE_LIST;

        @XStreamAlias("OPERATORID")
        @XStreamAsAttribute
        String operatorID;

        @XStreamAlias("TRANSACTIONSTARTTIME")
        @XStreamAsAttribute
        String transactionStartTime;

        public Body() {
            getLineRecipeList();
        }

        public String getLineName() {
            return lineName;
        }

        public void setLineName(String lineName) {
            this.lineName = lineName;
        }

        public List<LineRecipe> getLineRecipeList() {
            if (LINE_RECIPE_LIST == null) {
                LINE_RECIPE_LIST = new ArrayList<>();
            }
            return LINE_RECIPE_LIST;
        }

        public void setLineRecipeList(List<LineRecipe> lineRecipeList) {
            this.LINE_RECIPE_LIST = lineRecipeList;
        }

        public String getOperatorID() {
            return operatorID;
        }

        public void setOperatorID(String operatorID) {
            this.operatorID = operatorID;
        }

        public String getTransactionStartTime() {
            return transactionStartTime;
        }

        public void setTransactionStartTime(String transactionStartTime) {
            this.transactionStartTime = transactionStartTime;
        }
    }


    @XStreamAlias("LINE_RECIPE")
    public static class LineRecipe {
        @XStreamAlias("RECIPEEVENTTYPE")
        String recipeEventType;
        @XStreamAlias("LINERECIPENAME")
        String lineRecipeName;
        @XStreamAlias("TIMEOUT_UNIT_LIST")
        String TIMEOUT_UNIT_LIST;
        @XStreamAlias("CIMOFF_UNIT_LIST")
        String CIMOFF_UNIT_LIST;
        @XStreamAlias("UNIT_LIST")
        String UNIT_LIST;

        public LineRecipe() {
//            getUnitList();
        }


        public String getRecipeEventType() {
            return recipeEventType;
        }

        public void setRecipeEventType(String recipeEventType) {
            this.recipeEventType = recipeEventType;
        }

        public String getLineRecipeName() {
            return lineRecipeName;
        }

        public void setLineRecipeName(String lineRecipeName) {
            this.lineRecipeName = lineRecipeName;
        }

//    public List<TimeOutUnit> getTimeOutUnits() {
//        if (TIMEOUT_UNIT_LIST == null) {
//            TIMEOUT_UNIT_LIST = new ArrayList<>();
//        }
//        return TIMEOUT_UNIT_LIST;
//    }
//
//    public void setTimeOutUnits(List<TimeOutUnit> timeOutUnits) {
//        this.TIMEOUT_UNIT_LIST = timeOutUnits;
//    }
//
//    public List<CimoffUnit> getCimoffUnits() {
//        if (CIMOFF_UNIT_LIST == null) {
//            CIMOFF_UNIT_LIST = new ArrayList<>();
//        }
//        return CIMOFF_UNIT_LIST;
//    }
//
//    public void setCimoffUnits(List<CimoffUnit> cimoffUnits) {
//        this.CIMOFF_UNIT_LIST = cimoffUnits;
//    }

//        public List<Unit> getUnitList() {
//            if (UNIT_LIST == null) {
//                UNIT_LIST = new ArrayList<>();
//            }
//            return UNIT_LIST;
//        }
//
//        public void setUnitList(List<Unit> unitList) {
//            this.UNIT_LIST = unitList;
//        }

        public String getTIMEOUT_UNIT_LIST() {
            return TIMEOUT_UNIT_LIST;
        }

        public void setTIMEOUT_UNIT_LIST(String TIMEOUT_UNIT_LIST) {
            this.TIMEOUT_UNIT_LIST = TIMEOUT_UNIT_LIST;
        }

        public String getCIMOFF_UNIT_LIST() {
            return CIMOFF_UNIT_LIST;
        }

        public void setCIMOFF_UNIT_LIST(String CIMOFF_UNIT_LIST) {
            this.CIMOFF_UNIT_LIST = CIMOFF_UNIT_LIST;
        }

        public String getUNIT_LIST() {
            return UNIT_LIST;
        }

        public void setUNIT_LIST(String UNIT_LIST) {
            this.UNIT_LIST = UNIT_LIST;
        }
    }
}

我的测试类是这样的:

``

package com.example.rvxmldemo.testmdoel;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import java.io.*;

public class Test12 {
    public static void main(String[] args) {
        String xml = "F:\xml\message.xml";
        String s = readFile(xml);
        Message message = toBean(s, Message.class);
        System.out.println(message);


    }

    public static <T> T toBean(String xmlStr, Class<T> cls) {
        XStream xstream = new XStream(new DomDriver());
        xstream.setClassLoader(cls.getClassLoader());
        xstream.processAnnotations(cls);
        T obj = (T) xstream.fromXML(xmlStr);
        return obj;
    }

    /**
     * 一次性读取全部文件数据
     *
     * @param strFile
     * @return
     */
    public static String readFile(String strFile) {
        String s = "";
        try {
            InputStream is = new FileInputStream(strFile);
            int iAvail = is.available();
            byte[] bytes = new byte[iAvail];
            is.read(bytes);
            s = new String(bytes);
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }
}

启动之后报错:

` Security framework of XStream not explicitly initialized, using predefined black list on your own risk.

Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field com.example.rvxmldemo.testmdoel.Message$LineRecipe.LINE_RECIPE
---- Debugging information ----
message             : No such field com.example.rvxmldemo.testmdoel.Message$LineRecipe.LINE_RECIPE
field               : LINE_RECIPE
class               : com.example.rvxmldemo.testmdoel.Message$LineRecipe
required-type       : com.example.rvxmldemo.testmdoel.Message$LineRecipe
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path                : /MESSAGE/BODY/LINE_RECIPE_LIST/LINE_RECIPE
class[1]            : com.example.rvxmldemo.testmdoel.Message$Body
required-type[1]    : com.example.rvxmldemo.testmdoel.Message$Body
class[2]            : com.example.rvxmldemo.testmdoel.Message
required-type[2]    : com.example.rvxmldemo.testmdoel.Message
version             : 1.4.14

? at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.handleUnknownField(AbstractReflectionConverter.java:520)
? at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:371)
? at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
? at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
? at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

从报错来看是说找不到这个字段LINE_RECIPE,而这个字段的定义是在Body
image.png

一看这个字段在Body里的定义就感觉有点奇怪了,可能题主要理解一下这个两个注解的差别了

@XStreamAlias
@XStreamImplicit

尤其是@XStreamImplicit,如果能明白@XStreamImplicit的含义,其实也就豁然开朗了,主要在其中的Implicit这个单词,这个是隐式的意思,打开@XStreamImplicit注解也说得比较明白,人家就是处理隐式集合
image.png

那什么是隐式集合呢?看官方解释吧(图中有个小bug,应该是隐式,不是隐藏,打错了)

image.png

结合解释你再回过头看看,你就明白了,你的xml文件里的元素LINE_RECIPE_LIST实际就是一个显示的集合标志嘛,所以干嘛这时候要去用@XStreamImplicit呢?直接@XStreamAlias("LINE_RECIPE_LIST")就够了啊

所以改法的话,很简单,删除@XStreamImplicit(itemFieldName = "LINE_RECIPE")即可

 @XStreamAlias("LINE_RECIPE_LIST")
 List<LineRecipe> LINE_RECIPE_LIST;

当然你非要想使用@XStreamImplicit注解也行,那就把xml文件中的LINE_RECIPE变为隐式的集合即可嘛

怎么变呢?结合刚才官方那个截图,没有外面的集合标签就行啦,所以如果你想要写成

 @XStreamImplicit(itemFieldName = "LINE_RECIPE")
 List<LineRecipe> LINE_RECIPE_LIST;

xml文件就必须改为
image.png

当然你作为解析方,一般来说呢,比较卑微。。。估计没有权利让对方改接口,所以,只能用第一种方案,不过我额外这么一提,主要还是想让题主更清楚@XStreamImplicit的用法吧,希望能对你有所帮助

那...拜了个拜~(* ̄rǒ ̄)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...