emfjson / emfjson-jackson

JSON Binding for Eclipse Modeling Framework
https://emfjson.github.io
Other
80 stars 23 forks source link

Collection<Resource> deserialization behaviour #63

Closed lex-em closed 8 years ago

lex-em commented 9 years ago

I find that deserialization of Resource collection is not correct. My code:

    @RequestMapping(value = "/packagesDi", method = RequestMethod.GET)
    @ResponseBody
    public Collection<Resource> getPackagesDi(){
        ...
        return Arrays.asList(resource, resourceDi);
    }

    @RequestMapping(value = "/packagesDi", method = RequestMethod.POST)
    @ResponseBody
    public void setPackagesDi(@RequestBody List<Resource> resources){
        ...
    }

I'm trying to POST json from first method to second and get List of 2 Resource, but both resources is the same object. First transmitted resource contains 168 eobjects and 30 contents and second contains 54 eobject and 1 content. Recieved resource contains 222 eobject and 31 contents.

ghillairet commented 9 years ago

What code actually does the de/serialization from/to JSON, are you using Jackson's ObjectMapper?

lex-em commented 9 years ago

I have next configuration:


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
        mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        JacksonOptions options = new JacksonOptions.Builder().withID(true).withTypes(true).build();
        mapper.registerModule(new EMFModule(resourceSet(), options));
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(mapper);
        converters.add(converter);
    }

    @Bean
    public ResourceSet resourceSet(){
        if (resourceSet == null) {
            resourceSet = new ResourceSetImpl();
            resourceSet.getPackageRegistry().put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
            resourceSet.getPackageRegistry().put(UMLDIPackage.eNS_URI, UMLDIPackage.eINSTANCE);
            Map<String, Object> extensionToFactoryMap = resourceSet.getResourceFactoryRegistry()
                    .getExtensionToFactoryMap();
            extensionToFactoryMap.put("json", new JsonResourceFactoryCit());
            extensionToFactoryMap.put("umldi", new UMLDIResourceFactoryImpl());
            resourceSet.setURIConverter(URIConverter.INSTANCE);
            UMLResourcesUtil.init(resourceSet);
            Map<URI, URI> uriMap = resourceSet.getURIConverter().getURIMap();
            try(Stream<Path> files = Files.list(Paths.get("model"))){
                files
                        .map(file -> file.toFile().getName())
                        .filter(file -> file.endsWith(".uml") || file.endsWith(".umldi"))
                        .forEach(file -> uriMap.put(URI.createURI(file), URI.createURI("model/"+file)));
            } catch (IOException e) {
                e.printStackTrace();
            }
//            uriMap.put(URI.createURI("http://www.omg.org/spec/UML/20131001/UMLDI"), URI.createURI("model/"+file));
            resourceSet.getResource(URI.createURI("pathmap://UML_PROFILES/Standard.profile.uml#_0"), true);
            resourceSet.getResource(URI.createURI("ISO20022Profile.profile.uml"), true);
        }
        return resourceSet;
    }
ghillairet commented 9 years ago

The way to convert a JSON array into a list of resources with the object mapper can only be achieved by telling the object mapper that you want a list, like this

List<Resource> resources = mapper.readValue(data, List.class)

See http://www.baeldung.com/jackson-collection-array

ghillairet commented 8 years ago

Closing for now.