2013-10-04 2 views
0

Я создаю тестовое приложение для достижения преобразования из строки JSON в объект Employee перед передачей его на контроллер.Spring MVC Custom Converter для данных JSON не работает

Вот основные шаги выполнены

  • Создание Employee.java класса: объект домена
  • Создание EmployeeManagementController.java класса: Spring MVC контроллер для управления Работнику
  • Создание EmployeeConverter.java: Пользовательский конвертер для преобразования строки JSON в объект Employee.
  • Создание сотрудника-servlet.xml: файл конфигурации Spring
  • Создание web.xml: Дескриптор развертывания

Employee.java

package com.bluebench.training.domain; 

import org.springframework.stereotype.Component; 

@Component("employee") 
public class Employee { 

    private PersonalDetail personal; 
    private EducationDetail education; 
    private WorkExperienceDetail experience; 


    // Getters and Setters 

} 

другой домен объекты также определены

EmployeeManagementController.java

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 

import com.bluebench.training.domain.Employee; 

@Controller 
public class EmployeeManagementController { 

    @RequestMapping(value="/ems/add/employee",method=RequestMethod.POST,consumes="application/json",produces="application/json") 
    public @ResponseBody int addEmployee(@RequestBody Employee emp){ 
     System.out.println("RAGHAVE"); 
     System.out.println(emp.getPersonal().getName()); 
     int empId = 20; 
     return empId; 
    } 




} 

EmployeeConverter.java

package com.bluebench.training.converter; 

import java.io.IOException; 

import org.codehaus.jackson.JsonParseException; 
import org.codehaus.jackson.map.JsonMappingException; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.springframework.core.convert.converter.Converter; 

import com.bluebench.training.domain.Employee; 

public class EmployeeConverter implements Converter<String,Employee>{ 

    @Override 
    public Employee convert(String json) { 
     System.out.println("Inside convert()"); 
     Employee emp = null; 
     try { 
      emp = new ObjectMapper().readValue(json,Employee.class); 
     } catch (JsonParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (JsonMappingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }   
     return emp; 
    } 




} 

сотрудник-servlet.xml

<?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: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-3.0.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.0.xsd 
       http://www.springframework.org/schema/mvc 
       http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

       <context:component-scan base-package="com.bluebench.training"/> 

       <mvc:annotation-driven conversion-service="conversionService"/> 

       <mvc:default-servlet-handler/>   

       <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
        <property name="mediaTypes"> 
         <map> 
          <entry key="json" value="application/json" /> 
          <entry key="xml" value="text/xml" /> 
          <entry key="htm" value="text/html" /> 
         </map> 
        </property> 
        <property name="defaultContentType" value="text/html"/> 
       </bean> 

       <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> 
        <property name="converters"> 
         <list> 
          <bean class="com.bluebench.training.converter.EmployeeConverter"/> 
         </list> 
        </property> 
       </bean> 

      </beans> 

web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 
    <display-name>PROJECT_38_SpringMVCRESTFul</display-name> 

    <servlet> 
    <servlet-name>employee</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>employee</servlet-name> 
    <url-pattern>/*</url-pattern> 
    </servlet-mapping> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/employee-servlet.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 



</web-app> 

Я использую Firefox RestClient для его проверки.

Здесь находится JSON, который правильно отображает объект Employee.

{"personal":{"name":"Raghave","age":33,"phoneNumber":"9594511111","address":"101, software appartment, software land , mumbai"},"education":{"qualifications":[{"insititute":"Amity University","degree":"Bachelor of Science","yearOfPassing":"2007","percentage":62.0}]},"experience":{"experience":[{"companyName":"QTBM","designation":"Programmer","years":3,"salary":12000.0},{"companyName":"Polaris","designation":"Software Developer","years":1,"salary":24000.0},{"companyName":"Ness","designation":"Senior Software Engineer","years":2,"salary":50000.0},{"companyName":"JPMC","designation":"Senior Applications Developer","years":1,"salary":120000.0}]}} 

Там не исключение брошено, и контроллер делает получить объект Employee в методе addEmployee(). Но его не через конвертер. Конвертер не вызывается. Я не знаю почему? Я не хочу использовать init binders или @Valid. Я хотел знать, где я ошибаюсь. как заставить его работать?

+0

Прежде всего, выберите '@ Component' и' 'декларацию. Не используйте оба. –

+0

Извините, мой плохой, я изменюсь, тем больше вопрос, как заставить конвертер вызываться. – RaghaveShukla

ответ

3

Вы путаете поддержку конвертации общего типа Spring, которая использует Конвертеры и ConversionService с поддержкой преобразования HTTP-сообщений, которая специально предназначена для преобразования веб-запросов и ответов и понимает типы мультимедиа (например, application/json, которые вы используете). Преобразование HTTP-сообщений использует экземпляр HttpMessageConverter.

В этом случае вам не нужен специальный конвертер. Spring MappingJacksonHttpMessageConverter используется для автоматического преобразования.Преобразование может быть выполнено автоматически, потому что, предположительно (вы не размещали сеттеры, поэтому я делаю обоснованное предположение), методы настройки в Employee соответствуют JSON, то есть setName, setAge, setPhoneNumber и т. Д.

Возможно, код, который у вас есть, уже работает. Вы можете безопасно удалить свой собственный конвертер, иметь ту же функциональность и иметь меньше кода для поддержки. Если вы действительно хотите использовать собственный конвертер, вам нужно будет реализовать HttpMessageConverter и настроить его перед/вместо MappingJacksonHttpMessageConverter.

+0

Спасибо Энди за то, что он разогнал разницу между конвертерами сообщений. Источник весны весной потерял в определении четких границ между редакторами Web Argument Resolvers, InitBinders и Property, преобразователями типов, преобразователями сообщений и форматировщиками. Но это также приводит меня к определению моего фактического требования. Это был просто PoC, который я могу применить конвертер в ситуации, которая потребует Custom Conversion. Я думаю, что Message Converter - это то, что мне действительно нужно для моего реального приложения. – RaghaveShukla

+0

В нашем реальном приложении мы пытаемся добиться прямого преобразования JSON в PDF, то есть JSON будет разбираться с пользовательскими объектами, такими как Document, которые, в свою очередь, содержат ссылки на объекты Itext. Проблема состоит в том, что у нескольких компонентов Itext нет геттеров и/или сеттеров, которые заставляют Jackson Parser бросать исключения, если я непосредственно пытаюсь сопоставить JSON с объектами itext. Для этого мне нужно создать промежуточный пользовательский объект TemplateMapper, который выполняет необходимое копирование в объект Itext, поэтому я не могу перейти без конвертера или в качестве упомянутого конвертера сообщений. Можете ли вы предоставить какой-либо ресурс? – RaghaveShukla

+0

Это, вероятно, лучше решать в отдельном вопросе. Вы либо захотите зарегистрировать пользовательский HttpMessageConverter, либо настроить Jackson ObjectMapper, который использует Spring для автоматического преобразования. –

Смежные вопросы