복붙노트

[SPRING] 사용자 지정 HTTP 메시지 변환기가 사용되지 않음, 415 지원되지 않는 미디어 형식

SPRING

사용자 지정 HTTP 메시지 변환기가 사용되지 않음, 415 지원되지 않는 미디어 형식

나는 컨트롤러에 전달되기 전에 XML 문자열을 Employee 객체로 변환하기위한 테스트 애플리케이션을 작성 중이다. 나는 SAX 파서와 몇 가지 복잡한 규칙을 사용하여 XML 파싱을 포함하는 실제 사용 사례에서 사용할 사용자 지정 HTTP 메시지 변환기를 테스트하는 것이기 때문에 JAXB 변환기를 사용하고 싶지 않습니다.

수행 된 주요 단계는 다음과 같습니다.

Employee.java

@Component
@XmlRootElement(name="employee")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee{

@XmlElement(name="name")
String name;
@XmlElement(name="designation")
String designation;
@XmlElement(name="skill")
String skill;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}

}

EmployeeManagementController.java

@Controller
@RequestMapping(value="/emp")
public class EmployeeManagementController {

    @RequestMapping(value="/add/employee", method=RequestMethod.POST, consumes="text/html")
    public void addEmployee(@RequestBody Employee employee){
        System.out.println("Employee Name : "+employee.getName());
        System.out.println("Employee Designation : "+employee.getDesignation());
        System.out.println("Employee Skill : "+employee.getSkill());

    }


}

EmployeeConverter.java

@Component
public class EmployeeConverter extends AbstractHttpMessageConverter<Employee>{

    @Override
    protected Employee readInternal(Class<? extends Employee> arg, HttpInputMessage inputMsg) throws IOException,
            HttpMessageNotReadableException {
        // TODO Auto-generated method stub
        Map<String,String> paramMap = getPostParameter(inputMsg);
        BufferedReader file =  new BufferedReader(new StringReader(paramMap.get("xml")));
        Employee employee = null;
        JAXBContext jaxbContext;
        try {
            jaxbContext = JAXBContext.newInstance(Employee.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            employee = (Employee) jaxbUnmarshaller.unmarshal(file);
        } catch (JAXBException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(employee);
        return employee;
    }

    @Override
    protected boolean supports(Class<?> type) {
        if(type.getSimpleName().equalsIgnoreCase("Employee")){
            return true;
        }
        return false;
    }

    @Override
    protected void writeInternal(Employee arg0, HttpOutputMessage arg1)
            throws IOException, HttpMessageNotWritableException {
        // TODO Auto-generated method stub

    }

    private Map<String,String> getPostParameter(HttpInputMessage input) throws IOException{
        String payload = null;
        String[] params = null;
        BufferedReader buf = new BufferedReader(new InputStreamReader(input.getBody()));
        Map<String,String> paramMap = new HashMap<String,String>();

        String line="";
        while((line = buf.readLine())!=null){
            payload = payload+line;
        }

        if(payload.contains("&")){
            params = payload.split("&");
            for(String param : params){
                paramMap.put(param.split("=")[0],param.split("=")[1]);
            }
        }

        return paramMap;
    }


}

employee-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"
                xmlns:util="http://www.springframework.org/schema/util"
                xsi:schemaLocation="http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                http://www.springframework.org/schema/context 
                http://www.springframework.org/schema/context/spring-context-3.1.xsd
                http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
                http://www.springframework.org/schema/util
                http://www.springframework.org/schema/util/spring-util-3.1.xsd">

         <mvc:default-servlet-handler/> 

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

         <mvc:annotation-driven>
            <mvc:message-converters>
                <bean class="com.converter.EmployeeConverter"/>             
            </mvc:message-converters>
        </mvc:annotation-driven>

        <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 class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">    
                <util:list id="beanList">
                    <ref bean="employeeConverter"/>       
                </util:list>
            </property>
        </bean>  -->

        <!-- <bean id="employeeConverter" class="com.converter.EmployeeConverter"/> -->



</beans>

을 포함한다.

<?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>TestConverter</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>    
  </welcome-file-list>

  <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를 사용할 때 응답이 다음과 같이 표시됩니다. 415 Unsupported Media Type.

RestClient에서 Content-Type 및 Accept 헤더를 text / xml로 설정하고 본문에 다음 XML 문자열을 매개 변수로 전달합니다.

xml=<employee><name>Jack</name><designation>Account Director</designation><skill>Commuication</skill></employee>

누군가가 도움을 줄 수 있으며 어떤 변화가 필요한지 알려주시겠습니까? 나는 또한 메시지 변환기를 등록하기 위해 AnnotationMethodHandlerAdapter를 사용하려고 시도했다.

해결법

  1. ==============================

    1.1. 미디어 유형 설정

    1. 미디어 유형 설정

    Spring에서 제공하는 일부 HttpMessageConverter 구현 (예 : 'MappingJackson2HttpMessageConverter ')과 구현을 비교하면 supportedMediaTypes를 정의하지 못한 것을 알 수 있습니다.

    AbstractHttpMessageConverter 를 확장 한 HttpMessageConverter의 일반적인 방법은 초 생성자 인 AbstractHttpMessageConverter (MediaType supportedMediaType)를 사용하여 생성자에서 미디어 유형을 설정하는 것입니다.

     public class EmployeeConverter extends AbstractHttpMessageConverter<Employee> {
          public EmployeeConverter() {
                super(new MediaType("text", "xml", Charset.forName("UTF-8")));
          }
     }
    

    BTW 1 : 당신은 또한 하나 이상의 미디어 유형을 등록 할 수 있습니다 **

    super(MediaType.APPLICATION_XML,
          MediaType.TEXT_XML,
          new MediaType("application", "*+xml")); 
    

    BTW 2 : XML Conterter에 대해 AbstractXmlHttpMessageConverter 에서 확장해야한다고 생각해야합니다.

    2. 계산기 등록

    <mvc:annotation-driven>
        <mvc:message-converters>
           ...
           <bean class="com.example.YourConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>
    

    의 가장 큰 단점은 이것이 기본 설정을 대체한다는 것입니다. 따라서 모든 기본 HttpMessageConverter를 명시 적으로 등록해야합니다.

    기본 메시지 변환을 유지하려면 를 사용해야합니다.

  2. from https://stackoverflow.com/questions/21349030/custom-http-message-converter-not-being-used-415-unsupproted-media-type by cc-by-sa and MIT license