4

java.lang.ClassCastException: cn.yunnet.wxhotel.utils.TestMicropay cannot be cast to cn.yunnet.wxhotel.utils.TestMicropay

TestMicropayEntity:

   package cn.yunnet.wxhotel.utils;

public class TestMicropay {
    private String return_code;
    private String return_msg;
    public String getReturn_code() {
        return return_code;
    }
    public void setReturn_code(String return_code) {
        this.return_code = return_code;
    }
    public String getReturn_msg() {
        return return_msg;
    }
    public void setReturn_msg(String return_msg) {
        this.return_msg = return_msg;
    }
}

----xstream

package me.chanjar.weixin.common.util.xml;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.basic.DoubleConverter;
import com.thoughtworks.xstream.converters.basic.FloatConverter;
import com.thoughtworks.xstream.converters.basic.IntConverter;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.security.NoTypePermission;
import com.thoughtworks.xstream.security.NullPermission;
import com.thoughtworks.xstream.security.PrimitiveTypePermission;

import java.io.Writer;

public class XStreamInitializer {

  public static XStream getInstance() {
    XStream xstream = new XStream(new XppDriver() {

      @Override
      public HierarchicalStreamWriter createWriter(Writer out) {
        return new PrettyPrintWriter(out, getNameCoder()) {
          protected String PREFIX_CDATA = "<![CDATA[";
          protected String SUFFIX_CDATA = "]]>";
          protected String PREFIX_MEDIA_ID = "<MediaId>";
          protected String SUFFIX_MEDIA_ID = "</MediaId>";
          @Override
          protected void writeText(QuickWriter writer, String text) {
            if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
              writer.write(text);
            } else if (text.startsWith(PREFIX_MEDIA_ID) && text.endsWith(SUFFIX_MEDIA_ID)) {
              writer.write(text);
            } else {
              super.writeText(writer, text);
            }

          }
        };
      }
    });
    xstream.ignoreUnknownElements();
    xstream.setMode(XStream.NO_REFERENCES);
    xstream.addPermission(NullPermission.NULL);
    xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
    return xstream;
  }

}

invoke:

String text = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名错误]]></return_msg>";
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", TestMicropay.class);
Object o = xstream.fromXML(responseContent);
TestMicropay t = (TestMicropay)o;

exception:

java.lang.ClassCastException: cn.yunnet.wxhotel.utils.TestMicropay cannot be cast to cn.yunnet.wxhotel.utils.TestMicropay
    at cn.yunnet.wxhotel.utils.wechat.AdvancedWxMpServiceImpl.micropayPost(AdvancedWxMpServiceImpl.java:106) ~[classes/:na]

-why when i use in main() invoke,it's work normal;but when used in SpringMVC controller,throw this Exception??

li.G
  • 41
  • 4

1 Answers1

11

In Java, getting class cast exception where both classes are exactly the same it says that equality of two classes depends on class name and loader.

XStream must be using different class loader.

The quick solution would be to set same class loader current thread is using:

XStream xStream = new XStream();
xStream.setClassLoader(Thread.currentThread().getContextClassLoader());
Community
  • 1
  • 1
Modestas
  • 126
  • 3
  • 5
  • It worked for me but still not clear how come XStream got different loader. Thanks though. – Shiv May 20 '23 at 13:05