Krushna
Krushna

Reputation: 6070

Null pointer exception using jackson processor spring mvc 3.1

I have the below pojo which I'm trying to serialize and deserialize using spring support for jackson processor,Below is my POJO class

public class Contract {
String term;
private List<Payment> paymentList=new ArrayList<Payment>();
public String getTerm() {
    return term;
}
public void setTerm(String term) {
    this.term = term;
}
public List<Payment> getPaymentList() {
    return paymentList;
}
public void setPaymentList(List<Payment> paymentList) {
    this.paymentList = paymentList;
}

}

In the above class if there is a list,I am getting null pointer exception when I am using JUnit test cases mentioned below:

package com.budco.vsc.jsonmapping;

import static org.junit.Assert.assertEquals;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.samples.mvc.ajax.account.Contract;
import org.springframework.samples.mvc.ajax.json.ConversionServiceAwareObjectMapper;
import org.springframework.util.Assert;



 public class ContractJsonBindingTests{

Logger log = LoggerFactory.getLogger(ContractJsonBindingTests.class);

private MappingJacksonHttpMessageConverter converter;

private ObjectMapper objectMapper;


private String testPayload = "{\"term\":\"krish\"}";
@Before
public void setUp() {
    FormattingConversionServiceFactoryBean factoryBean = new FormattingConversionServiceFactoryBean();
    factoryBean.afterPropertiesSet();
    ConversionService conversionService = factoryBean.getObject();

    objectMapper = new ConversionServiceAwareObjectMapper(conversionService);
    converter = new MappingJacksonHttpMessageConverter();
    converter.setObjectMapper(objectMapper);
}

@Test
@SuppressWarnings("unchecked")
public void testAnnotationDrivenJsonConversion() throws Exception {
    MockHttpInputMessage inputMessage = new MockHttpInputMessage(testPayload.getBytes("UTF-8"));
    MediaType jsonType = new MediaType("application", "json");
    inputMessage.getHeaders().setContentType(jsonType);
    Contract contract = (Contract) converter.read((Class) Contract.class, inputMessage);
    Assert.notNull(contract);
    log.debug(contract.toString());

    MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
    converter.write(contract, jsonType, outputMessage);
    log.debug(outputMessage.getBody().toString());
    assertEquals("Incoming and outgoing JSON representations expected to match", testPayload, outputMessage.getBody().toString());
}

private static class MockHttpInputMessage implements HttpInputMessage {

    private final HttpHeaders headers = new HttpHeaders();

    private final InputStream body;

    public MockHttpInputMessage(byte[] contents) {
        Assert.notNull(contents, "'contents' must not be null");
        this.body = new ByteArrayInputStream(contents);
    }

    public HttpHeaders getHeaders() {
        return headers;
    }

    public InputStream getBody() throws IOException {
        return body;
    }
}

public class MockHttpOutputMessage implements HttpOutputMessage {

    private final HttpHeaders headers = new HttpHeaders();

    private final ByteArrayOutputStream body = new ByteArrayOutputStream();

    public HttpHeaders getHeaders() {
        return headers;
    }

    public OutputStream getBody() throws IOException {
        return body;
    }

    public byte[] getBodyAsBytes() {
        return body.toByteArray();
    }

    public String getBodyAsString(Charset charset) {
        byte[] bytes = getBodyAsBytes();
        return new String(bytes, charset);
    }
}
}

The stack trace is

java.lang.NullPointerException
at org.springframework.samples.mvc.ajax.json.FormatAnnotationIntrospector.findDeserializer(FormatAnnotationIntrospector.java:33)
at org.codehaus.jackson.map.AnnotationIntrospector$Pair.findDeserializer(AnnotationIntrospector.java:1058)
at org.codehaus.jackson.map.deser.BasicDeserializerFactory.findDeserializerFromAnnotation(BasicDeserializerFactory.java:462)
at org.codehaus.jackson.map.deser.BeanDeserializerFactory.constructSettableProperty(BeanDeserializerFactory.java:606)
at org.codehaus.jackson.map.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:460)
at org.codehaus.jackson.map.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:149)
at org.codehaus.jackson.map.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:116)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createDeserializer(StdDeserializerProvider.java:342)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:264)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:244)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:111)
at org.codehaus.jackson.map.deser.StdDeserializer.findDeserializer(StdDeserializer.java:482)
at org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:271)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:348)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:303)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:244)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:111)
at org.codehaus.jackson.map.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:182)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createDeserializer(StdDeserializerProvider.java:332)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:264)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:244)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:111)
at org.codehaus.jackson.map.deser.StdDeserializer.findDeserializer(StdDeserializer.java:482)
at org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:271)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:348)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:303)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:244)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:111)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findTypedValueDeserializer(StdDeserializerProvider.java:127)
at org.codehaus.jackson.map.ObjectMapper._findRootDeserializer(ObjectMapper.java:2046)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1980)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1331)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at com.budco.vsc.jsonmapping.ContractJsonBindingTests.testAnnotationDrivenJsonConversion(ContractJsonBindingTests.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
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.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
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)

Note:- If I'm removing the list property(paymentList) from the POJO then there is no problem. That means the above is not working when the POJO content some collection properties.If any body have any idea please help me.

EDIT: The payment class

public class Payment {

private BigDecimal amount;
private String payType;
private String transactionType;
private String chargeOrCancelFlag;
private String type;
private String authCode;
private Date authRequestDate;
private String authStatus;
private String authTransactioncode;
private SystemUser systemUser;
private String mailOrEmailInvoice;
private String monthlyBillOnDay;
private CreditCard creditCard;


public BigDecimal getAmount() {
    return amount;
}
public void setAmount(BigDecimal amount) {
    this.amount = amount;
}
public String getPayType() {
    return payType;
}
public void setPayType(String payType) {
    this.payType = payType;
}
public String getTransactionType() {
    return transactionType;
}
public void setTransactionType(String transactionType) {
    this.transactionType = transactionType;
}
public String getChargeOrCancelFlag() {
    return chargeOrCancelFlag;
}
public void setChargeOrCancelFlag(String chargeOrCancelFlag) {
    this.chargeOrCancelFlag = chargeOrCancelFlag;
}
public String getType() {
    return type;
}
public void setType(String type) {
    this.type = type;
}
public String getAuthCode() {
    return authCode;
}
public void setAuthCode(String authCode) {
    this.authCode = authCode;
}
public Date getAuthRequestDate() {
    return authRequestDate;
}
public void setAuthRequestDate(Date authRequestDate) {
    this.authRequestDate = authRequestDate;
}
public String getAuthStatus() {
    return authStatus;
}
public void setAuthStatus(String authStatus) {
    this.authStatus = authStatus;
}
public String getAuthTransactioncode() {
    return authTransactioncode;
}
public void setAuthTransactioncode(String authTransactioncode) {
    this.authTransactioncode = authTransactioncode;
}
public SystemUser getSystemUser() {
    return systemUser;
}
public void setSystemUser(SystemUser systemUser) {
    this.systemUser = systemUser;
}
public String getMailOrEmailInvoice() {
    return mailOrEmailInvoice;
}
public void setMailOrEmailInvoice(String mailOrEmailInvoice) {
    this.mailOrEmailInvoice = mailOrEmailInvoice;
}
public String getMonthlyBillOnDay() {
    return monthlyBillOnDay;
}
public void setMonthlyBillOnDay(String monthlyBillOnDay) {
    this.monthlyBillOnDay = monthlyBillOnDay;
}
public CreditCard getCreditCard() {
    return creditCard;
}
public void setCreditCard(CreditCard creditCard) {
    this.creditCard = creditCard;
}

 }

The credit card class

   public class CreditCard {

private String type;
private String cardNumber;
private String name;
private String securityCode;
private String expirationDate;
private String firstFourDigit;
private String secondFourDigit;
private String thirdFourDigit;
private String lastFourDigits;
private String zipCode;



public void setMonth(String month){
    if(expirationDate==null)
        expirationDate=month;
    else
        expirationDate=month+"/"+expirationDate;
}

public void setYear(String year){
    if(expirationDate==null)
        expirationDate=year;
    else
        expirationDate=expirationDate+"/"+year;
}

public String getMonth() {
    return "";
}

public String getYear() {
    return "";
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public String getCardNumber() {
    if (cardNumber == null)
        cardNumber = firstFourDigit + secondFourDigit + thirdFourDigit
                + lastFourDigits;
    return cardNumber;
}

public void setCardNumber(String cardNumber) {
    this.cardNumber = cardNumber;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getSecurityCode() {
    return securityCode;
}

public void setSecurityCode(String securityCode) {
    this.securityCode = securityCode;
}

public String getExpirationDate() {
    return expirationDate;
}

public void setExpirationDate(String expirationDate) {
    this.expirationDate = expirationDate;
}

public String getFirstFourDigit() {
    return firstFourDigit;
}

public String getSecondFourDigit() {
    return secondFourDigit;
}

public String getThirdFourDigit() {
    return thirdFourDigit;
}

public String getLastFourDigits() {
    return lastFourDigits;
}

public void setLastFourDigits(String lastFourDigits) {
    this.lastFourDigits = lastFourDigits;
}

public void setFirstFourDigit(String firstFourDigit) {
    this.firstFourDigit = firstFourDigit;
}

public void setSecondFourDigit(String secondFourDigit) {
    this.secondFourDigit = secondFourDigit;
}

public void setThirdFourDigit(String thirdFourDigit) {
    this.thirdFourDigit = thirdFourDigit;
}

public String getZipCode() {
    return zipCode;
}

public void setZipCode(String zipCode) {
    this.zipCode = zipCode;
}

  }

Upvotes: 1

Views: 3197

Answers (1)

user180100
user180100

Reputation:

public void setMonth(String month){
    // ...
}

public void setYear(String year){
    // ...
}

Are the problem here. Because during introspection spring looks for a field with name being name of the setXXX, without set.

see FormatAnnotationIntrospector source code

EDIT (proposed solution):

public class CreditCard {
    public static class ExpirationDate {
        private String month;
        private String year;

        // getters, setter

        @Override
        public String toString() {
            return month + "/" + year;
        }
    }

    private String type;
    private String cardNumber;
    private String name;
    private String securityCode;
    private ExpirationDate expirationDate;
    private String firstFourDigit;
    private String secondFourDigit;
    private String thirdFourDigit;
    private String lastFourDigits;
    private String zipCode;

    public void setExpirationDate(ExpirationDate expDate){
        this.expirationDate = expDate;
    }

    public ExpirationDate getExpirationDate(){
        return this.expirationDate;
    }

    // other getters, setters
}

Upvotes: 2

Related Questions