春季rest和Jsonp

我试图让我的Springrest控制器返回jsonp,但我没有快乐

完全相同的代码工作正常,如果我想返回json但我有一个要求返回jsonp我已添加到转换器中我找到了在线执行jsonp转换的源代码

我使用的是Spring 4.1.1.RELEASE和Java 7

任何帮助是极大的赞赏

这是有问题的代码

MVC-调度-servlet.xml中

                                    

com.webapp.handler.MappingJacksonJsonpView

 package com.webapp.handler; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; public class MappingJacksonJsonpView extends MappingJackson2JsonView { /** Local log variable. **/ private static final Logger LOG = LoggerFactory.getLogger(MappingJacksonJsonpView.class); /** * Default content type. Overridable as bean property. */ public static final String DEFAULT_CONTENT_TYPE = "application/javascript"; @Override public String getContentType() { return DEFAULT_CONTENT_TYPE; } /** * Prepares the view given the specified model, merging it with static * attributes and a RequestContext attribute, if necessary. * Delegates to renderMergedOutputModel for the actual rendering. * @see #renderMergedOutputModel */ @Override public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.info("Entered render Method :{}", request.getMethod()); if("GET".equals(request.getMethod().toUpperCase())) { LOG.info("Request Method is a GET call"); Map params = request.getParameterMap(); if(params.containsKey("callback")) { String callbackParam = params.get("callback")[0]; LOG.info("callbackParam:{}", callbackParam); response.getOutputStream().write(new String(callbackParam + "(").getBytes()); super.render(model, request, response); response.getOutputStream().write(new String(");").getBytes()); response.setContentType(DEFAULT_CONTENT_TYPE); } else { LOG.info("Callback Param not contained in request"); super.render(model, request, response); } } else { LOG.info("Request Method is NOT a GET call"); super.render(model, request, response); } } } 

控制器方法问题

  @RequestMapping(value = { "/sources"}, method = RequestMethod.GET, produces={MediaType.ALL_VALUE, "text/javascript", "application/javascript", "application/ecmascript", "application/x-ecmascript", "application/x-javascript", MediaType.APPLICATION_JSON_VALUE}) @ResponseBody public Object getSources(@PathVariable(value = API_KEY) String apiKey, @RequestParam(value = "searchTerm", required = true) String searchTerm, @RequestParam(value = "callBack", required = false) String callBack) { LOG.info("Entered getSources - searchTerm:{}, callBack:{} ", searchTerm, callBack); List searchVOList = myServices.findSources(searchTerm); if (CollectionUtils.isEmpty(searchVOList)) { LOG.error("No results exist for the searchterm of {}", searchTerm); return searchVOList; } LOG.debug("{} result(s) exist for the searchterm of {}", searchVOList.size(), searchTerm); LOG.info("Exiting getSources"); return searchVOList; } 

** Jquery Ajax代码**

 $.ajax({ type: "GET", url: "http://localhost:8080/my-web/rest/sources, data: { "searchTerm": request.term }, //contentType: "application/json; charset=utf-8", //dataType: "json", contentType: "application/javascript", dataType: "jsonp", success: function(data) { alert("success"); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert("Failure"); } }); 

我得到的错误堆栈跟踪的片段如下

 org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:168) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:198) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) ~[spring-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) [servlet-api.jar:na] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:na] 

正如关于Spring 4.1发布的spring.io 博客所述:

jackson现在支持JSONP。 对于响应体方法声明@ControllerAdvice,如下所示。 对于基于视图的渲染,只需在MappingJackson2JsonView上配置JSONP查询参数名称。

 @ControllerAdvice private static class JsonpAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpAdvice() { super("callback"); } } 

[…]在4.1中,@ ControllerAdvice也可以实现ResponseBodyAdvice,在这种情况下,它将在控制器方法返回之后但在写入响应之前被调用并因此被提交。 这有很多有用的应用程序,@ JsonView JSONP已经作为它构建的两个例子。

从MappingJackson2JsonView获取的Javadoc:

设置JSONP请求参数名称。 每次请求具有其中一个参数时,生成的JSON将被包装到一个名为JSONP请求参数值指定的函数中。 默认配置的参数名称为“jsonp”和“callback”。

你不需要自己实现这些东西。 只需重用Spring Framework中的位。

Spring Boot示例

以下简单的Spring Boot应用程序演示了如何在Spring MVC 4.1中使用构建JSONP支持。 示例至少需要Spring Boot 1.2.0.RC1。

 import com.fasterxml.jackson.annotation.JsonAutoDetect; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice; import java.util.Collections; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @RestController @SpringBootApplication class Application { @JsonAutoDetect(fieldVisibility = ANY) static class MyBean { String attr = "demo"; } @ControllerAdvice static class JsonpAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpAdvice() { super("callback"); } } @Bean public HttpMessageConverters customConverters() { return new HttpMessageConverters(false, Collections. >singleton(new MappingJackson2HttpMessageConverter())); } @RequestMapping MyBean demo() { return new MyBean(); } @RequestMapping(produces = APPLICATION_JSON_VALUE) String demo2() { return "demo2"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

URL http://localhost:8080/demo?callback=test将POJO转换为JSONP响应:

 test({"attr":"demo"}); 

URL http://localhost:8080/demo2?callback=testString转换为JSONP响应:

 test("demo2");