Results 1 to 6 of 6

Thread: RestTemplate, not marked as ignorable

  1. #1
    Join Date
    Aug 2009
    Location
    Paris
    Posts
    2

    Default RestTemplate, not marked as ignorable

    I have got the following situation :

    a webapp serving Spring Rest websevice :
    http://localhost:8080/webapp-domain/hotels/1.json

    a client webapp, I'm using a RestTemplate (defaults maintained)

    the two webapps are running within two jvms

    both client webapp and (REST) server webapp shares model-project (contains the JPA pojos)

    I'm doing a unit test from my client webapp to invoke my REST service, here are snippets from configurations and code files :


    applicationContext.xml
    Code:
    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
    <property name="messageConverters">
    <list>
    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
    </list>
    </property>
    </bean>
    The Pojo :
    Code:
    package fr.company.model;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.OneToMany;
    import javax.persistence.SequenceGenerator;
    import javax.persistence.Table;
    import javax.persistence.UniqueConstraint;
    
    import org.apache.commons.lang.builder.ToStringBuilder;
    import org.apache.commons.lang.builder.ToStringStyle;
    
    /**
     * Hotel model class
     * 
     */
    @Entity
    @Table(name = "hotel", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
    public class Hotel extends AbstractPersistable<Integer> {
    	private static final long serialVersionUID = -6186187114090017681L;
    
    	private Integer id;
    	private String code;
    	private String label;
    	private String description;
    	private List<Location> locations = new ArrayList<Location>(0);
    	private List<Room> rooms = new ArrayList<Room>(0);
    	private List<Booking> bookings = new ArrayList<Booking>(0);
    	private List<User> users = new ArrayList<User>(0);
    
    	/**
    	 * Default constructor
    	 */
    	public Hotel() {
    	}
    
    	/**
    	 * @{inheritDoc
    	 */
    	@Id
    	@Column(name = "id", unique = true, nullable = false)
    	@GeneratedValue(generator = "hotelIdGenerator")
    	@SequenceGenerator(name = "hotelIdGenerator", sequenceName = "hotel_id_seq")
    	public Integer getId() {
    		return this.id;
    	}
    
    	/**
    	 * @param id
    	 */
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	/**
    	 * @return
    	 */
    	@Column(name = "code", unique = true, nullable = false)
    	public String getCode() {
    		return this.code;
    	}
    
    	/**
    	 * @param code
    	 */
    	public void setCode(String code) {
    		this.code = code;
    	}
    
    	/**
    	 * @return
    	 */
    	@Column(name = "label")
    	public String getLabel() {
    		return this.label;
    	}
    
    	/**
    	 * @param label
    	 */
    	public void setLabel(String label) {
    		this.label = label;
    	}
    
    	/**
    	 * @return
    	 */
    	@Column(name = "description")
    	public String getDescription() {
    		return this.description;
    	}
    
    	/**
    	 * @param description
    	 */
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    	/**
    	 * @return
    	 */
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "hotel")
    	public List<Location> getLocations() {
    		return this.locations;
    	}
    
    	/**
    	 * @param locations
    	 */
    	public void setLocations(List<Location> locations) {
    		this.locations = locations;
    	}
    
    	/**
    	 * @return
    	 */
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "hotel")
    	public List<Room> getRooms() {
    		return this.rooms;
    	}
    
    	/**
    	 * @param rooms
    	 */
    	public void setRooms(List<Room> rooms) {
    		this.rooms = rooms;
    	}
    
    	/**
    	 * @return
    	 */
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "hotel")
    	public List<Booking> getBookings() {
    		return this.bookings;
    	}
    
    	/**
    	 * @param bookings
    	 */
    	public void setBookings(List<Booking> bookings) {
    		this.bookings = bookings;
    	}
    
    	/**
    	 * @return the users
    	 */
    	@ManyToMany(fetch = FetchType.LAZY)
    	@JoinTable(name = "user_hotel", 
    			joinColumns = { @JoinColumn(name = "hotel_id", nullable = false, updatable = false) }, 
    			inverseJoinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) })
    	public List<User> getUsers() {
    		return users;
    	}
    
    	/**
    	 * @param users the users to set
    	 */
    	public void setUsers(List<User> users) {
    		this.users = users;
    	}
    
    	/**
    	 * {@inheritDoc}
    	 */
    	@Override
    	public String toString() {
    		return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
    				.appendSuper(super.toString()).append("code", code).append(
    						"label", label).toString();
    	}
    }
    The Service :
    Code:
        @Override
        public HotelDto loadHotel(Integer id) {
    	Hotel hotel = restTemplate.getForObject(restServerHost + "/hotels/{id}.json", Hotel.class,
    		id);
    	return new HotelDto(hotel.getId());
        }

    Exception :
    Code:
    org.springframework.web.client.ResourceAccessException: I/O error: Unrecognized field "hotel" (Class fr.company.model.Hotel), not marked as ignorable
     at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1049d3; line: 1, column: 2]; nested exception is org.codehaus.jackson.map.JsonMappingException: Unrecognized field "hotel" (Class fr.company.model.Hotel), not marked as ignorable
     at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1049d3; line: 1, column: 2]
    	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:359)
    	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:307)
    	at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:177)
    	at fr.company.web.server.BookingServiceImpl.loadHotel(BookingServiceImpl.java:35)
    	at fr.company.web.server.BookingServiceGwtTest.testlLoadHotel(BookingServiceGwtTest.java:23)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.codehaus.jackson.map.JsonMappingException: Unrecognized field "hotel" (Class fr.company.model.Hotel), not marked as ignorable
     at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1049d3; line: 1, column: 2]
    	at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159)
    	at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:174)
    	at org.codehaus.jackson.map.deser.StdDeserializer.reportUnknownProperty(StdDeserializer.java:317)
    	at org.codehaus.jackson.map.deser.StdDeserializer.handleUnknownProperty(StdDeserializer.java:303)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:505)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:281)
    	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1282)
    	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:927)
    	at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:109)
    	at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:143)
    	at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:60)
    	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:352)
    	... 32 more

  2. #2
    Join Date
    Aug 2009
    Location
    Paris
    Posts
    2

    Thumbs up It's finally a MappingJackson issue

    After investigating the problem deeply, it appears that the problem is a Jackson parser nor than a spring one.

  3. #3
    Join Date
    Sep 2009
    Posts
    2

    Default

    Have you resolved the problem?
    I have the same problem

  4. #4
    Join Date
    Apr 2009
    Posts
    7

    Angry how did u fix it?

    yeah, if you fixed it, please post few lines describing your solution...

  5. #5

    Default

    To resolve this we need to set Fail_on_unknown_properties to false in jackson object mapper.

    It can be done either by including this class in path
    Code:
    @Component
    public class JsonObjectMapperConfiguration implements BeanPostProcessor {
    
        private static final Logger logger = Logger.getLogger(JsonObjectMapperConfiguration.class);
    
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof AnnotationMethodHandlerAdapter) {
                AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean;
                HttpMessageConverter<?>[] converters = adapter.getMessageConverters();
                for (HttpMessageConverter<?> converter : converters) {
                    if (converter instanceof MappingJacksonHttpMessageConverter) {
                        MappingJacksonHttpMessageConverter jsonConverter = (MappingJacksonHttpMessageConverter) converter;
                        ObjectMapper newObjectMapper = new ObjectMapper();
                        newObjectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                        jsonConverter.setObjectMapper(newObjectMapper);
                    }
                }
            }
            return bean;
        }
    
    
    }
    or by creating a new ObjectMapper as below and setting in {springconfig}.xml

    Code:
    ObjectMapper newObjectMapper = new ObjectMapper();
                        newObjectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
    bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">

  6. #6

    Default

    If you fail on unknown properties, all the attributes and children of that property will not get parsed. In the hotel example, that's the top level element, so there'd be nothing to get.

    Use this:

    Code:
    public class ExtendedMappingJacksonJsonView extends MappingJacksonJsonView {
    
    	@SuppressWarnings("unchecked")
    	@Override
    	protected Object filterModel(Map<String, Object> model)
    	{
    		Object result = super.filterModel(model);
    		if (!(result instanceof Map))
    		{
    			return result;
    		}
    		
    		Map map = (Map) result;
    		if (map.size() == 1)
    		{
    			return map.values().toArray()[0];
    
    		}
    		return map;
    	}
    }
    It'll create a JSON representation that Jackson knows how to parse.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •