热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spring-boot从控制器返回json和xml

如何解决《Spring-boot从控制器返回json和xml》经验,为你挑选了4个好方法。

我有一个spring-boot 1.1.7应用程序,它使用Thymeleaf作为UI的大部分内容,因此我的控制器的响应并没有真正成为一个问题.但是,现在我需要在用户通过URL提交请求时提供XML响应.

这是一个典型的请求:

http://localhost:9001/remote/search?sdnName=Victoria&address=123 Maple Ave

这是我的大多数gradle配置:

project.ext {
    springBootVersion = '1.1.7.RELEASE'
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion")
    compile("org.springframework.security:spring-security-web:4.0.0.M1")
    compile("org.springframework.security:spring-security-config:4.0.0.M1")
    compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:2.1.1.RELEASE')
    compile("org.springframework.boot:spring-boot-starter-actuator")
    compile('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.5.0')
}

这是我的控制器:

@Controller
public class RemoteSearchController {

    @Autowired
    private SdnSearchService sdnSearchService;

    @RequestMapping(value = "/remote/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
    public List search(@ModelAttribute SdnSearch sdnSearch) {
        List foundSdns = sdnSearchService.find( sdnSearch );
        return foundSdns;
}

这是我要返回的对象:

@Entity
public class Sdn {

    @Id
    private long entNum;
    private String sdnName;
...
//getters & setters here
}

我能够通过REST客户端(例如CocoaREST)接收请求并处理它.但是当我返回SDN列表时,我得到以下异常,即使我的classpath上有Jackson&jackson-dataformat-xml:

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:229)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:301)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:248)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:57)
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:299)

我的REST客户端包含一个"text/xml"的Accept Header(但是说实话,我宁愿他们不必设置它.理想情况下,对这个Controller的任何调用总是会得到XML,无论是否存在头文件).

有办法处理这个吗?我认为媒体转换器是包含在内的,只是返回控制器告诉他们的内容?

解决方案:请参阅下面的我发布的答案.



1> Mickael..:

我有完全相同的问题,我在Spring文档网站上找到了解决方案:这里

在综合中,我将以下依赖项添加到pom.xml我的项目中:


     com.fasterxml.jackson.dataformat
     jackson-dataformat-xml
 

然后我将以下代码块添加到服务必须返回的类中:

 import javax.xml.bind.annotation.XmlRootElement;

 @XmlRootElement
 public class Greeting {...}

它奏效了.



2> sonoerin..:

解决方案:我在下面使用了两个答案的组合(非常感谢!).我发布在这里以防其他人需要帮助.

我的改装控制器:

@Controller
public class RemoteSearchController {

    @Autowired
    private SdnSearchService sdnSearchService;

    @RequestMapping(value = "/remote/search", method = RequestMethod.GET, produces = { "application/xml", "text/xml" }, cOnsumes= MediaType.ALL_VALUE )
    @ResponseBody
    public SdnSearchResults search(@ModelAttribute SdnSearch sdnSearch) {
        List foundSdns = sdnSearchService.find( sdnSearch );
        SdnSearchResults results = new SdnSearchResults();
        results.setSdns( foundSdns );
        return results;
    }
}

在我的客户端上,我设置了请求标头:

内容类型:应用程序/文本接受:text/xml我认为最终问题是我的客户端头文件没有正确设置,所以我可能不必进行一些这些更改.但我喜欢包含结果列表的SearchResults类的想法:

@XmlRootElement
public class SdnSearchResults {
    private List sdns;
...
}



3> manish..:

创建一个新类可能更好:

public class SdnSearchResult {
  private List sdns;
  ...
}

然后,现有类需要稍作改动,如下所示:

public interface SdnSearchService {
  SdnSearchResult find(SdnSearch sdnSearch);
}

@Controller
public class UISearchController {
  @Autowired
  private SdnSearchService sdnSearchService;

  @RequestMapping("/search")
  public ModelAndView search(@ModelAttribute SdnSearch sdnSearch) {
    return new ModelAndView("pages/search/results", "sdns", sdnSearchService.find(sdnSearch).getSdns());
  }
}

完成此操作后,另一个控制器必须编码为:

@Controller
public class RemoteSearchController {
  @Autowired
  private SdnSearchService sdnSearchService;

  @RequestMapping("/remote/search")
  @ResponseBody
  public SdnSearchResult search(@RequestBody SdnSearch sdnSearch) {
    return sdnSearchService.find(sdnSearch);
  }
}

从代码中快速解释更改:

    @RequestBody将自动将整个HTTP请求主体反序列化为SdnSearch实例.外部应用程序通常将请求数据作为HTTP正文提交,因此@RequestBody将确保自动发生对Java对象的反序列化.

    @ResponseBody将根据外部客户端的功能和类路径上可用的库自动序列化返回值.如果Jackson在类路径上可用且客户端已指示他们可以接受JSON,则返回值将自动作为JSON发送.如果JRE为1.7或更高(这意味着JAX包含在JRE中)并且客户端已指示它们可以接受XML,则返回值将自动以XML格式发送.

    List需要更改以SdnSearchResult确保应用程序可以使用单个控制器方法交换JSON,XML,RSS和ATOM格式,因为XML(和基于XML的格式)需要在输出上使用根标记,而List无法将其转换为.

完成这些更改后,启动REST客户端,例如Chrome的Postman扩展程序,并/remote/search使用以下信息提交请求:

    请求标头Accepts设置为application/json.

    请求标头Content-Type设置为application/json.

    请求正文设置为JSON字符串{ "sdnName" : "Victoria", "address" : "123 Maple Ave" }.

这将为您提供JSON响应.



4> Andy Wilkins..:

您已将控制器方法标记为生成application/xml响应(produces = MediaType.APPLICATION_XML_VALUE).请求的accept header(Accept: text/xml)不匹配,因此Spring确定您的search方法无法处理请求.

根据您的具体要求,有几种不同的方法可以在服务器上修复此问题:

您可以produces完全删除该属性

您可以指定多种媒体类型: produces = { "application/xml", "text/xml" }


推荐阅读
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 基于Axis、XFire、CXF的webservice客户端调用示例
    本文介绍了如何使用Axis、XFire、CXF等工具来实现webservice客户端的调用,以及提供了使用Java代码进行调用的示例。示例代码中设置了服务接口类、地址,并调用了sayHello方法。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 本文介绍了Sencha Touch的学习使用心得,主要包括搭建项目框架的过程。作者强调了使用MVC模式的重要性,并提供了一个干净的引用示例。文章还介绍了Index.html页面的作用,以及如何通过链接样式表来改变全局风格。 ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
author-avatar
金针菇滚滚夹着五根水葱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有