2017-02-20 7 views
0

Я использую Moxy для сериализации API на основе JSON. Работает как шарм, за исключением одной мелочи: Сериализация поля с URL как fieldName не работает.MOXY unmarshal JSON с URL-адресом в поле имени

Вот что я пытаюсь достичь:

Foo.class:

package test; 

import javax.xml.bind.annotation.XmlElement; 

public class Foo { 

@XmlElement(name = "http://www.foo.bar") 
private String bar; 

private String foo; 

@XmlElement(name = "_foo_bar") 
private String fooBar; 

public String getBar() { 
    return bar; 
} 

public void setBar(String bar) { 
    this.bar = bar; 
} 

public String getFoo() { 
    return foo; 
} 

public void setFoo(String foo) { 
    this.foo = foo; 
} 

public String getFooBar() { 
    return fooBar; 
} 

public void setFooBar(String fooBar) { 
    this.fooBar = fooBar; 
} 

} 

тест:

package test; 

import java.io.StringReader; 
import java.util.HashMap; 
import java.util.Map; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.transform.stream.StreamSource; 
import org.eclipse.persistence.jaxb.JAXBContextProperties; 

public class TestMoxy { 

public static void main(String[] args) { 
    String json = "{\"http://www.foo.bar\":\"BAR\",\"foo\":\"FOO\",\"_foo_bar\":\"FOOBAR\"}"; 
    System.out.println(json); 

    Foo f = unMarshal(json); 
    System.out.println(f.getBar()); 
    System.out.println(f.getFoo()); 
    System.out.println(f.getFooBar()); 
} 

public static Foo unMarshal(final String jsonString) { 
    try { 
     Map<String, Object> properties = new HashMap<String, Object>(2); 
     properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); 
     properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); 

     JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);  
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     StringReader reader = new StringReader(jsonString); 
     Foo f = unmarshaller.unmarshal(new StreamSource(reader),Foo.class).getValue(); 
     return f; 
    } catch (final JAXBException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
} 

Теперь выход таков:

{"http://www.foo.bar":"BAR","foo":"FOO","_foo_bar":"FOOBAR"} 
null 
FOO 
FOOBAR 

Итак, вопрос: как исправить unmarshalling первого атрибута?

+0

Чтобы использовать библиотеку Moxy для маршализацию JSON вам нужно [указать время выполнения EclipseLink] (http://www.eclipse.org/eclipselink/documentation/2.4/moxy /runtime001.htm#CACFEGHC): '-Djavax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory', это не ответ, просто чтобы помочь расследовать. – James

+0

Спасибо Джеймс, я забыл упомянуть об этом, но я сделал это через файл в classpath 'jaxb.properties', содержащий: 'javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory' – user7595421

ответ

0

Это похоже на ошибку в MOXy для меня, я протестировал несколько различных комбинаций специальных символов, MOXy, похоже, не похож на : или \\, эти исключения исключений; где http://, https:// и даже http//, похоже, игнорируются (это было с использованием зависимости org.eclipse.persistence:org.eclipse.persistence.moxy:2.6.0. Если вам действительно нужна возможность обрабатывать имена свойств, которые формируются как URL, то, возможно, взглянуть на другие библиотеки. Мне нравится FasterXML Jackson.

Я был в состоянии получить ваш пример работает довольно быстро с Джексоном .:

Maven зависимостей:

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.7.0</version> 
</dependency> 

Foo.class:

package test; 

import com.fasterxml.jackson.annotation.JsonProperty; 

public class Foo { 

    @JsonProperty(value = "http://www.foo.bar") 
    private String bar; 

    private String foo; 

    @JsonProperty(value = "_foo_bar") 
    private String fooBar; 

    public String getBar() { 
     return bar; 
    } 

    public void setBar(String bar) { 
     this.bar = bar; 
    } 

    public String getFoo() { 
     return foo; 
    } 

    public void setFoo(String foo) { 
     this.foo = foo; 
    } 

    public String getFooBar() { 
     return fooBar; 
    } 

    public void setFooBar(String fooBar) { 
     this.fooBar = fooBar; 
    } 
} 

Главная/Тест класс

package test; 

import com.fasterxml.jackson.databind.ObjectMapper; 
import java.io.IOException; 

public class TestMoxy { 

    public static void main(String[] args) { 
     String json = "{\"http://www.foo.bar\":\"BAR\",\"foo\":\"FOO\",\"_foo_bar\":\"FOOBAR\"}"; 
     System.out.println(json); 

     Foo f = unMarshal(json); 
     System.out.println(f.getBar()); 
     System.out.println(f.getFoo()); 
     System.out.println(f.getFooBar()); 
    } 

    public static Foo unMarshal(String jsonString) { 
     try { 
      ObjectMapper mapper = new ObjectMapper(); 
      return mapper.readValue(jsonString, Foo.class); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return new Foo(); 
    } 
}