son*_*rin 16 spring-mvc spring-boot
我有一个spring-boot 1.1.7应用程序,它使用Thymeleaf作为UI的大部分内容,因此我的控制器的响应并没有真正成为一个问题.但是,现在我需要在用户通过URL提交请求时提供XML响应.
这是一个典型的请求:
http://localhost:9001/remote/search?sdnName=Victoria&address=123 Maple Ave
Run Code Online (Sandbox Code Playgroud)
这是我的大多数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')
}
Run Code Online (Sandbox Code Playgroud)
这是我的控制器:
@Controller
public class RemoteSearchController {
@Autowired
private SdnSearchService sdnSearchService;
@RequestMapping(value = "/remote/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
public List<Sdn> search(@ModelAttribute SdnSearch sdnSearch) {
List<Sdn> foundSdns = sdnSearchService.find( sdnSearch );
return foundSdns;
}
Run Code Online (Sandbox Code Playgroud)
这是我要返回的对象:
@Entity
public class Sdn {
@Id
private long entNum;
private String sdnName;
...
//getters & setters here
}
Run Code Online (Sandbox Code Playgroud)
我能够通过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)
Run Code Online (Sandbox Code Playgroud)
我的REST客户端包含一个"text/xml"的Accept Header(但是说实话,我宁愿他们不必设置它.理想情况下,对这个Controller的任何调用总是会得到XML,无论是否存在头文件).
有办法处理这个吗?我认为媒体转换器是包含在内的,只是返回控制器告诉他们的内容?
解决方案:请参阅下面的我发布的答案.
Mic*_*ael 14
我有完全相同的问题,我在Spring文档网站上找到了解决方案:这里
在综合中,我将以下依赖项添加到pom.xml我的项目中:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
然后我将以下代码块添加到服务必须返回的类中:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Greeting {...}
Run Code Online (Sandbox Code Playgroud)
它奏效了.
son*_*rin 10
解决方案:我在下面使用了两个答案的组合(非常感谢!).我发布在这里以防其他人需要帮助.
我的改装控制器:
@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<Sdn> foundSdns = sdnSearchService.find( sdnSearch );
SdnSearchResults results = new SdnSearchResults();
results.setSdns( foundSdns );
return results;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的客户端上,我设置了请求标头:
内容类型:应用程序/文本接受:text/xml我认为最终问题是我的客户端头文件没有正确设置,所以我可能不必进行一些这些更改.但我喜欢包含结果列表的SearchResults类的想法:
@XmlRootElement
public class SdnSearchResults {
private List<Sdn> sdns;
...
}
Run Code Online (Sandbox Code Playgroud)
创建一个新类可能更好:
public class SdnSearchResult {
private List<Sdn> sdns;
...
}
Run Code Online (Sandbox Code Playgroud)
然后,现有类需要稍作改动,如下所示:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
完成此操作后,另一个控制器必须编码为:
@Controller
public class RemoteSearchController {
@Autowired
private SdnSearchService sdnSearchService;
@RequestMapping("/remote/search")
@ResponseBody
public SdnSearchResult search(@RequestBody SdnSearch sdnSearch) {
return sdnSearchService.find(sdnSearch);
}
}
Run Code Online (Sandbox Code Playgroud)
从代码中快速解释更改:
@RequestBody将自动将整个HTTP请求主体反序列化为SdnSearch实例.外部应用程序通常将请求数据作为HTTP正文提交,因此@RequestBody将确保自动发生对Java对象的反序列化.@ResponseBody将根据外部客户端的功能和类路径上可用的库自动序列化返回值.如果Jackson在类路径上可用且客户端已指示他们可以接受JSON,则返回值将自动作为JSON发送.如果JRE为1.7或更高(这意味着JAX包含在JRE中)并且客户端已指示它们可以接受XML,则返回值将自动以XML格式发送.List<Sdn>需要更改以SdnSearchResult确保应用程序可以使用单个控制器方法交换JSON,XML,RSS和ATOM格式,因为XML(和基于XML的格式)需要在输出上使用根标记,而List<Sdn>无法将其转换为.完成这些更改后,启动REST客户端,例如Chrome的Postman扩展程序,并/remote/search使用以下信息提交请求:
Accepts设置为application/json.Content-Type设置为application/json.{ "sdnName" : "Victoria", "address" : "123 Maple Ave" }.这将为您提供JSON响应.
您已将控制器方法标记为生成application/xml响应(produces = MediaType.APPLICATION_XML_VALUE).请求的accept header(Accept: text/xml)不匹配,因此Spring确定您的search方法无法处理请求.
根据您的具体要求,有几种不同的方法可以在服务器上修复此问题:
produces完全删除该属性produces = { "application/xml", "text/xml" }| 归档时间: |
|
| 查看次数: |
62121 次 |
| 最近记录: |