1. 程式人生 > >Restlet 2.1.4中 匪夷所思的ObjectRepresentation的建構函式

Restlet 2.1.4中 匪夷所思的ObjectRepresentation的建構函式

OneCoder使用Restlet最新版2.1.4開發樣例,卻一直丟擲異常:

Exception in thread “main” java.lang.IllegalArgumentException : The serialized representation must have this media type: application/x-java-serialized-object or this one: application/x-java-serialized-object+xml
          at org.restlet.representation.ObjectRepresentation.(ObjectRepresentation.java:203)
     at org.restlet.representation.Objec tRepresentation.(ObjectRepresentation.java:114)

無論怎麼設定MediaType都無效,無奈只能檢視次建構函式的原始碼:

public ObjectRepresentation(Representation serializedRepresentation,
            final ClassLoader classLoader) throws IOException,
            ClassNotFoundException, IllegalArgumentException {
        super(MediaType.APPLICATION_JAVA_OBJECT);


        if (
serializedRepresentation.getMediaType().equals( MediaType. APPLICATION_JAVA_OBJECT)) { if (!VARIANT_OBJECT_BINARY_SUPPORTED ) { throw new IllegalArgumentException( "SECURITY WARNING: The usage of ObjectInputStream when " +
"deserializing binary presentations from unstrusted " + "sources can lead to malicious attacks. As pointed " + "here (https://github.com/restlet/restlet-framework-java/issues/778), " + "the ObjectInputStream class is able to force the JVM to execute unwanted " + "Java code. Thus, the support of such format has been disactivated " + "by default. You can activate this support by turning on the following system property: " + "org.restlet.representation.ObjectRepresentation.VARIANT_OBJECT_BINARY_SUPPORTED." ); } setMediaType(MediaType.APPLICATION_JAVA_OBJECT ); InputStream is = serializedRepresentation.getStream(); ObjectInputStream ois = null; if (classLoader != null) { ois = new ObjectInputStream(is) { @Override protected Class<?> resolveClass( java.io.ObjectStreamClass desc) throws java.io.IOException, java.lang.ClassNotFoundException { return Class . forName(desc.getName(), false, classLoader); } }; } else { ois = new ObjectInputStream(is); } this.object = (T) ois.readObject(); if (is.read() != -1) { throw new IOException( "The input stream has not been fully read."); } ois.close(); } else if (VARIANT_OBJECT_XML_SUPPORTED && serializedRepresentation.getMediaType().equals( MediaType.APPLICATION_JAVA_OBJECT_XML )) { if (!VARIANT_OBJECT_XML_SUPPORTED ) { throw new IllegalArgumentException( "SECURITY WARNING: The usage of XMLDecoder when " + "deserializing XML presentations from unstrusted " + "sources can lead to malicious attacks. As pointed " + "here (http://blog.diniscruz.com/2013/08/using-xmldecoder-to-execute-server-side.html), " + "the XMLDecoder class is able to force the JVM to " + "execute unwanted Java code described inside the XML " + "file. Thus, the support of such format has been " + "disactivated by default. You can activate this " + "support by turning on the following system property: " + "org.restlet.representation.ObjectRepresentation.VARIANT_OBJECT_XML_SUPPORTED." ); } setMediaType(MediaType.APPLICATION_JAVA_OBJECT_XML ); InputStream is = serializedRepresentation.getStream(); java.beans.XMLDecoder decoder = new java.beans.XMLDecoder(is); this.object = (T) decoder.readObject(); if (is.read() != -1) { throw new IOException( "The input stream has not been fully read."); } decoder.close(); } throw new IllegalArgumentException( "The serialized representation must have this media type: " + MediaType.APPLICATION_JAVA_OBJECT .toString() + " or this one: " + MediaType.APPLICATION_JAVA_OBJECT_XML .toString()); }

驚呆的發現,最後的throw new IllegalArgumentException 邏輯被赤裸裸的暴露在外面,也就是不論上面走的是if還是else,最終都會走到這裡丟擲異常結束。這不免讓我一頭霧水,回頭檢視2.1.2版本的原始碼,發現丟擲異常的程式碼是寫在最後的else塊裡的,這可就大不相同了。

我只能以我目前粗淺的瞭解,懷疑這是restlet的一個粗心的bug,我已經給restlet發了郵件諮詢了該問題,等待回覆中。目前,我也只能降到2.1.2版本的restlet進行開發,在2.1.2版上無此問題。

注:已確認是bug。