Moh*_*han 12 java xml spring json spring-mvc
我需要编写一个休息服务,它接受XML/JSON作为输入(POST方法)和XML/JSON作为输出(基于输入格式).我尝试过以下方法来实现这一点,但没有帮助.Endpoint方法同时接受XML/JSON但在响应时它总是根据@RequestMapping -produces中指定的顺序提供JSON或XML.任何帮助都将非常感谢.
我的端点方法:
@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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
春天-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>
Run Code Online (Sandbox Code Playgroud)
Json输入:
{
"id":2014,
"name":"test",
"graduationtime":"09/05/2014",
"courses":[
{
"courseName":"Math",
"score":150
},
{
"courseName":"Che",
"score":150
}
]
}
Run Code Online (Sandbox Code Playgroud)
XML输入:
<?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>
Run Code Online (Sandbox Code Playgroud)
man*_*ish 21
使用相同控制器处理不同数据格式的最佳实践是让框架完成计算编组和解组机制的所有工作.
第1步:使用最少的控制器配置
@RequestMapping(value = "/getxmljson", method = RequestMethod.POST)
@ResponseBody
public Student processXMLJsonRequest(@RequestBody Student student) {
return student;
}
Run Code Online (Sandbox Code Playgroud)
没有必要指定consumes和produces这里.例如,考虑您可能希望将来使用相同的方法处理其他格式,例如Google Protocol Buffers,EDI等.保持控制器免受攻击,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>
Run Code Online (Sandbox Code Playgroud)
让视图解析器决定如何读取传入数据以及如何将其写回.
第3步:使用
Accepts和Content-TypeHTTP标头
使用正确的HTTP标头值命中控制器将强制ContentNegotiatingViewResolver使用适当的数据表示自动编组和解组数据.
如果要以JSON格式交换数据,请将两个标头都设置为application/json.如果您想要XML,请将两者都设置为application/xml.
如果您不想使用HTTP标头(理想情况下应该这样),您只需添加.json或添加.xmlURL即可ContentNegotiatingViewResolver.
您可以查看我使用您的代码片段创建的示例应用程序,该代码片段适用于JSON和XML.
Gag*_*lra 10
除了Manish上面的答案,如果你不想使用基于xml的配置,请使用这个基于java的配置代替 -
@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;
}
Run Code Online (Sandbox Code Playgroud)
注册一个过滤器来拦截每个请求,将其转换HttpServletRequest为一个实现HttpServletRequestWrapper并返回headerContent-Type的值Accept。例如,您可以注册一个名为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);
}
}
Run Code Online (Sandbox Code Playgroud)
它将当前请求包装在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);
}
}
Run Code Online (Sandbox Code Playgroud)
HttpMessageConverter这个包装器告诉 spring mvc根据请求的值选择一个Content-Type。如果请求正文Content-Type是application/xml,则响应将为XML。否则,响应将为JSON。
另一个解决方案是在每个请求中手动设置Accept标头Content-Type并避免所有这些黑客行为。
| 归档时间: |
|
| 查看次数: |
48790 次 |
| 最近记录: |