2016-02-08 3 views
6

मुझे एक बाकी सेवा लिखनी है जो एक इनपुट (POST विधि) और एक्सएमएल/जेएसओएन आउटपुट (इनपुट प्रारूप के आधार पर) के रूप में एक्सएमएल/जेएसओएन स्वीकार करता है। मैंने इसे प्राप्त करने के लिए नीचे दिए गए दृष्टिकोण की कोशिश की है लेकिन इससे मदद नहीं मिली है। एंडपॉइंट विधि एक्सएमएल/जेएसओएन दोनों को स्वीकार करती है लेकिन इसका जवाब देने पर हमेशा @RequestMapping -produces में निर्दिष्ट क्रम के आधार पर JSON या XML देता है। किसी भी मदद की वास्तव में सराहना की जाएगी ।एक्सएमएल/जेएसओएन अनुरोध और प्रतिक्रिया को स्वीकार/वापस करना - स्प्रिंग एमवीसी

मेरे endpoint विधि:

@RequestMapping(value = "/getxmljson", method = RequestMethod.POST,produces={"application/json","application/xml"}, 
     consumes={"application/json", "application/xml"}) 
public @ResponseBody Student processXMLJsonRequest(@RequestBody Student student) 
     throws Exception { 
    System.out.println("*************Inside Controller"); 
    return student; 
} 

POJO कक्षा: Student.java

import java.io.Serializable; 
import java.util.ArrayList; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 

import com.fasterxml.jackson.annotation.JsonIgnore; 
import com.fasterxml.jackson.annotation.JsonPropertyOrder; 

@XmlRootElement(name = "student") 
@XmlType(propOrder = {"id", "name", "graduationTime", "courses"}) 
@JsonPropertyOrder({"id", "name", "graduationTime", "courses"}) 
public class Student implements Serializable { 
    private static final long serialVersionUID = 1L; 

    private int id; 
    private String name; 
    private String graduationTime; 
    private ArrayList<Course> courses = new ArrayList<Course>(); 

    @XmlElement 
    public int getId() { return id; } 
    @XmlElement 
    public String getName() { return name; } 
    @XmlElement 
    public String getGraduationTime() { return graduationTime; } 
    @XmlElement 
    public ArrayList<Course> getCourses() { return courses; } 

    public void setId(int value) { this.id = value; } 
    public void setName(String value) { this.name = value; } 
    public void setGraduationTime(String value) { this.graduationTime = value; } 
    public void setCourses(ArrayList<Course> value) { this.courses = value; } 

    @JsonIgnore 
    public String toString() { 
     return this.name + " - " 
       + graduationTime == null? "Unknown" : graduationTime.toString(); 
    } 

    public Student() {} 
    public Student(int id, String name, String graduationTime) { 
     this.id = id; 
     this.name = name; 
     this.graduationTime = graduationTime; 
    } 
} 

POJO कक्षा: Course.java

import java.io.Serializable; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 

import com.fasterxml.jackson.annotation.JsonPropertyOrder; 

@XmlRootElement(name = "course") 
@XmlType(propOrder = {"courseName", "score"}) 
@JsonPropertyOrder({"courseName", "score"}) 
public class Course implements Serializable { 
    private static final long serialVersionUID = 1L; 

    private String courseName; 
    private Integer score; 

    public @XmlElement String getCourseName() { return courseName; } 
    public @XmlElement Integer getScore() { return score; } 

    public void setCourseName(String value) { courseName = value; } 
    public void setScore(Integer value) { score = value; } 

    public Course() {} 
    public Course(String courseName, Integer score) { 
     this.courseName = courseName; 
     this.score = score; 
    } 
} 

वसंत-config.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/mvc" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:sws="http://www.springframework.org/schema/web-services" 
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:oxm="http://www.springframework.org/schema/oxm" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/web-services 
     http://www.springframework.org/schema/web-services/web-services-2.0.xsd 
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd 
     http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd 
     http://www.springframework.org/schema/util 
      http://www.springframework.org/schema/util/spring-util-2.5.xsd"> 

    <!-- DispatcherServlet Context: defines this servlet's request-processing 
     infrastructure --> 

    <!-- Enables the Spring MVC @Controller programming model --> 
    <annotation-driven /> 

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
     up static resources in the ${webappRoot}/resources directory --> 
    <resources mapping="/resources/**" location="/resources/" /> 

    <!-- Configure to plugin JSON as request and response in method handler --> 
    <beans:bean 
     class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> 
     <beans:property name="messageConverters"> 
      <beans:list> 
       <beans:ref bean="jsonMessageConverter" /> 
       <beans:ref bean="xmlMessageConverter" /> 
      </beans:list> 
     </beans:property> 
    </beans:bean> 

    <!-- Configure bean to convert JSON to POJO and vice versa --> 
    <beans:bean id="jsonMessageConverter" 
     class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
    </beans:bean> 

    <beans:bean id="xmlMessageConverter" 
     class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"> 
    </beans:bean> 

    <beans:bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> 

    </beans:bean> 

    <beans:bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" /> 
    <context:component-scan base-package="com.test" /> 

</beans:beans> 

Json इनपुट:

{ 
"id":2014, 
"name":"test", 
"graduationtime":"09/05/2014", 
"courses":[ 
{ 
"courseName":"Math", 
"score":150 
}, 
{ 
"courseName":"Che", 
"score":150 
} 
] 
} 

एक्सएमएल इनपुट:

<?xml version="1.0" encoding="UTF-8" ?> 
<student> 
<id>2014</id> 
<name>test</name> 
<graduationTime>09/05/2014</graduationTime> 
<courses> 
    <courseName>Math</courseName> 
    <score>150</score> 
</courses> 
<courses> 
    <courseName>Che</courseName> 
    <score>150</score> 
</courses> 
</student> 
+0

इस नमूना को देखो। http://howtodoinjava.com/spring/spring-restful/spring-rest-hello-world-xml-example/ –

उत्तर

0

एक फिल्टर है कि प्रत्येक अनुरोध को बीच में रोक रजिस्टर, HttpServletRequestWrapper के एक कार्यान्वयन में HttpServletRequest ताना और Accept हेडर के लिए Content-Type मान देता है। उदाहरण के लिए, आप निम्नलिखित की तरह SameInSameOutFilter नाम के एक फिल्टर रजिस्टर कर सकते हैं:

@Component 
public class SameInSameOutFilter extends GenericFilterBean { 
    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 
     SameInSameOutRequest wrappedRequest = new SameInSameOutRequest((HttpServletRequest) request); 
     chain.doFilter(wrappedRequest, response); 
    } 
} 

यह एक SameInSameOutRequest में वर्तमान अनुरोध लपेटता:

public class SameInSameOutRequest extends HttpServletRequestWrapper { 
    public SameInSameOutRequest(HttpServletRequest request) { 
     super(request); 
    } 

    @Override 
    public String getHeader(String name) { 
     if (name.equalsIgnoreCase("accept")) { 
      return getContentType(); 
     } 

     return super.getHeader(name); 
    } 
} 

इस आवरण को चुनने के लिए वसंत MVC बताता है एक HttpMessageConverter पर अनुरोध के Content-Type मूल्य आधारित। अगर अनुरोध निकाय का Content-Typeapplication/xml है, तो प्रतिक्रिया XML होगी। अन्यथा, प्रतिक्रिया JSON होगी।

अन्य समाधान प्रत्येक अनुरोध में Content-Type के साथ Accept शीर्षलेख मैन्युअल रूप से सेट करना है और इन सभी हैक्स से बचें।

13

एक ही नियंत्रक के साथ विभिन्न डेटा प्रारूपों को संभालने के लिए सबसे अच्छा अभ्यास फ्रेमवर्क को मार्शलिंग और अनैमरलिंग तंत्र को समझने के सभी कामों को करने देना है।

चरण 1: न्यूनतम नियंत्रक विन्यास का प्रयोग करें

@RequestMapping(value = "/getxmljson", method = RequestMethod.POST) 
@ResponseBody 
public Student processXMLJsonRequest(@RequestBody Student student) { 
    return student; 
} 

यहाँ consumes और produces निर्दिष्ट करने के लिए कोई जरूरत नहीं है। उदाहरण के तौर पर, इस बात पर विचार करें कि आप भविष्य में अन्य प्रारूपों जैसे कि Google प्रोटोकॉल बफर, ईडीआई इत्यादि को संभालने के लिए यह वही तरीका चाहते हैं। नियंत्रकों को consumes और produces से मुक्त रखने से आपको ग्लोबल कॉन्फ़िगरेशन के माध्यम से वैश्विक प्रारूपों के माध्यम से डेटा प्रारूप जोड़ने की सुविधा मिल जाएगी। नियंत्रक कोड संशोधित करें।

चरण 2: उपयोग ContentNegotiatingViewResolver बजाय RequestMappingHandlerAdapter

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
    <property name="defaultViews"> 
     <list> 
     <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/> 
     </list> 
    </property> 
    </bean> 

दृश्य समाधानकर्ता फैसला आने वाले डेटा को पढ़ने के लिए कैसे और कैसे इसे वापस लिखने के लिए करते हैं।

चरण 3: उपयोग Accepts और Content-Type HTTP हेडर

सही HTTP हेडर मूल्यों के साथ अपने नियंत्रक साधते ContentNegotiatingViewResolver बाध्य करेगा मार्शल करने के लिए और unmarshal डेटा स्वचालित रूप से उपयुक्त डेटा अभ्यावेदन का उपयोग कर।

यदि आप JSON प्रारूप में डेटा का आदान-प्रदान करना चाहते हैं, तो दोनों शीर्षलेखों को application/json पर सेट करें। यदि आप इसके बजाय एक्सएमएल चाहते हैं, तो दोनों को application/xml पर सेट करें।

यदि आप HTTP शीर्षलेख (जो आपको आदर्श रूप से करना चाहिए) का उपयोग नहीं करना चाहते हैं, तो आप URL में .json या .xml जोड़ सकते हैं और ContentNegotiatingViewResolver बाकी करेंगे।


आप my sample app है कि मैं अपने कोड के टुकड़े कि JSON और एक्सएमएल के लिए ठीक काम करता है का उपयोग कर बनाया बाहर की जाँच कर सकते हैं।

+0

एक्सएमएल को संभालने के लिए अतिरिक्त org.springframework.web.servlet.view.xml.MappingJackson2XmlView की आवश्यकता होगी। – anre

4

, ऊपर मनीष का जवाब देने के लिए शामिल करने से आप नहीं करना चाहते उपयोग एक्सएमएल आधारित विन्यास उपयोग इस जावा आधारित विन्यास instead-

@Bean 
public ViewResolver contentNegotiatingViewResolver() { 
    ContentNegotiatingViewResolver resolver = 
      new ContentNegotiatingViewResolver(); 

    List<View> views = new ArrayList<>(); 
    views.add(new MappingJackson2XmlView()); 
    views.add(new MappingJackson2JsonView()); 

    resolver.setDefaultViews(views); 
    return resolver; 
} 
0

मैं आपके जैसे ही समस्या का सामना करना पड़ करते हैं। नीचे मेरा समाधान और नमूना है।

नीचे निर्भरता है कि आप शामिल करने की जरूरत है:

 <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-core</artifactId> 
      <version>2.4.3</version> 
     </dependency> 
     <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-databind</artifactId> 
      <version>2.4.3</version> 
     </dependency> 
     <dependency> 
      <groupId>com.fasterxml.jackson.core</groupId> 
      <artifactId>jackson-annotations</artifactId> 
      <version>2.4.3</version> 
     </dependency> 
     <dependency> 
      <groupId>com.fasterxml.jackson.dataformat</groupId> 
      <artifactId>jackson-dataformat-xml</artifactId> 
      <version>2.4.3</version> 
     </dependency> 

डिस्पैचर-servlet.xml

<mvc:annotation-driven 
     content-negotiation-manager="contentManager" /> 

<bean id="contentManager" 
     class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> 
     <property name="favorPathExtension" value="false" /> 
     <property name="ignoreAcceptHeader" value="false" /> 
     <property name="defaultContentType" value="application/json" /> 
     <property name="useJaf" value="false" /> 
    </bean> 

और मेरे @RequestMapping (आप अपने खुद के अनुरोध मैपिंग का उपयोग कर सकते हैं)

@RequestMapping(value = "/testXMLJSON", 
      method = RequestMethod.GET, produces = { 
        MediaType.APPLICATION_XML_VALUE, 
        MediaType.APPLICATION_JSON_VALUE }) 
    @ResponseBody 
    public ArtworkContentMessageType testXMLJSON() 
    { 
     //this is GS1 xml standard mapping. 
     ArtworkContentMessageType resp = new ArtworkContentMessageType(); 
     StandardBusinessDocumentHeader standarBusinessDocumentHeader = new StandardBusinessDocumentHeader(); 
     resp.setStandardBusinessDocumentHeader(standarBusinessDocumentHeader); 
     ArtworkContentType artWorkContent = new ArtworkContentType(); 
     resp.getArtworkContent().add(artWorkContent); 

     return resp ; 
    } 
संबंधित मुद्दे