Error “Can not write a field name, expecting a value;” while Writing JSON on Spring MVC
The error started since i upgraded my jackson library, somehow it never happen before. This is my full stacktrace
com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1649) com.fasterxml.jackson.core.json.UTF8JsonGenerator.writeFieldName(UTF8JsonGenerator.java:186) com.edw.test.jackson.TestSerializer.serialize(TestSerializer.java:27) com.edw.test.jackson.TestSerializer.serialize(TestSerializer.java:19) com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130) com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1387) com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:889) org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:292) org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:106) org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231) org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:174) org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:113) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) javax.servlet.http.HttpServlet.service(HttpServlet.java:622) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
Looks like this error happen on my custom json serializer,
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <mvc:annotation-driven> <mvc:message-converters register-defaults="false"> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" p:objectMapper-ref="testObjectMapper"/> </mvc:message-converters> </mvc:annotation-driven> <context:component-scan base-package="com.edw.test.jackson"/> </beans>
And this is the content of my objectMapper java class,
package com.edw.test.jackson; import com.edw.test.jackson.bean.Test; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.stereotype.Component; @Component public class TestObjectMapper extends ObjectMapper { public TestObjectMapper() { super(); SimpleModule module = new SimpleModule(); module.addSerializer(Test.class, new TestSerializer()); registerModule(module); configure(SerializationFeature.INDENT_OUTPUT, false); } }
And as you can see, the main culprit is on class TestSerializer
package com.edw.test.jackson; import com.edw.test.jackson.bean.Test; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; public class TestSerializer extends JsonSerializer<Test> { @Override public void serialize(Test t, JsonGenerator jgen, SerializerProvider sp) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeRaw("{"); jgen.writeFieldName("test01"); jgen.writeRaw(t.getTest01()); jgen.writeFieldName("test02"); jgen.writeRaw(t.getTest02()); jgen.writeRaw("}"); jgen.writeEndObject(); } }
replacing writeFieldName method with writeRaw method solve my problem.
package com.edw.test.jackson; import com.edw.test.jackson.bean.Test; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; public class TestSerializer extends JsonSerializer<Test> { @Override public void serialize(Test t, JsonGenerator jgen, SerializerProvider sp) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeRaw("test01"); jgen.writeRaw(t.getTest01()); jgen.writeRaw("test02"); jgen.writeRaw(t.getTest02()); jgen.writeEndObject(); } }
Hope it helps 🙂