简体   繁体   English

用于JSON数据的Spring MVC自定义转换器无法正常工作

[英]Spring MVC Custom Converter for JSON data not working

I am creating a test application to to achieve conversion from JSON String to Employee Object before being passed to the controller. 我正在创建一个测试应用程序,以便在传递给控制器​​之前实现从JSON String到Employee Object的转换。

Here are the key steps performed 以下是执行的关键步骤

  • Creation of Employee.java Class : Domain Object 创建Employee.java类 :域对象
  • Creation of EmployeeManagementController.java class : Spring MVC Controller for Managing Employee 创建EmployeeManagementController.java类 :用于管理员工的Spring MVC控制器
  • Creation of EmployeeConverter.java : Custom Converter for Converting JSON String to Employee Object. 创建EmployeeConverter.java :用于将JSON字符串转换为Employee对象的自定义转换器。
  • Creation of employee-servlet.xml : Spring Configuration file 创建employee-servlet.xml :Spring配置文件
  • Creation of web.xml : The Deployment Descriptor 创建web.xml :部署描述符

Employee.java 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

}

other domain objects are also defined 还定义了其他域对象

EmployeeManagementController.java 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 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;
    }




}

employee-servlet.xml 员工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 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>

I am using Firefox RestClient to Test it. 我正在使用Firefox RestClient来测试它。

Here is the JSON which correctly maps to the Employee object. 这是正确映射到Employee对象的JSON。

{"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}]}}

There is no Exception thrown and the controller does receive the Employee Object in the addEmployee() method. 没有抛出Exception,控制器确实在addEmployee()方法中接收Employee对象。 But its not via converter. 但它不是通过转换器。 The Converter is not invoked. 不调用转换器。 I dont know why ? 我不知道为什么? I dont want to use init binders or @Valid. 我不想使用init绑定器或@Valid。 I wanted to know where am i going wrong. 我想知道我哪里出错了。 how to make it work? 如何使它工作?

You've confused Spring's general type conversion support that uses Converters and the ConversionService with its support for HTTP message conversion that is specifically designed for converting web requests and responses and understands media types (like application/json that you're using). 您已经混淆了Spring的一般类型转换支持,它使用Converters和ConversionService,支持HTTP消息转换,专门用于转换Web请求和响应,并理解媒体类型(如您正在使用的application / json)。 HTTP message conversion uses instance of HttpMessageConverter. HTTP消息转换使用HttpMessageConverter的实例。

You don't actually need a custom converter in this case. 在这种情况下,您实际上不需要自定义转换器。 Spring's MappingJacksonHttpMessageConverter is being used to perform the conversion automatically. Spring的MappingJacksonHttpMessageConverter用于自动执行转换。 The conversion can be performed automatically because, presumably (you haven't posted the setters so I'm making an educated guess), the setter methods in Employee match the JSON, ie setName, setAge, setPhoneNumber etc. 转换可以自动执行,因为,大概是(你没有发布setter所以我做了一个有根据的猜测),Employee中的setter方法匹配JSON,即setName,setAge,setPhoneNumber等。

Arguably, the code that you've got is already working. 可以说,你得到的代码已经可以使用了。 You can safely delete your custom converter, have the same functionality, and have less code to maintain. 您可以安全地删除自定义转换器,具有相同的功能,并且维护的代码更少。 If you really want to use a custom converter, you'll need to implement HttpMessageConverter and configure it before/in place of MappingJacksonHttpMessageConverter. 如果您真的想使用自定义转换器,则需要实现HttpMessageConverter并在/之前/代替MappingJacksonHttpMessageConverter进行配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM