添加 swagger lib 后,所有响应内容类型更改为 application/xml

After add swagger lib, all response content-type changed to application/xml

我是 swagger 和 springMVC 的菜鸟。上周我刚刚尝试将 swagger 集成到我们的系统中。在我部署新 war 之前,一切似乎都很好。我发现所有回复都自动更改为 xml 格式...任何人都可以指导我应该在哪里调查吗?我尝试了以下内容: 1. 恢复 spring 配置 exclude ,不工作。 2. 添加configureContentNegotiation configurer.defaultContentType(MediaType.APPLICATION_JSON), 不工作。 欢迎任何建议!谢谢!

我的 spring 配置文件:

@Configuration
@EnableWebMvc
@EnableSwagger2 //Loads the spring beans required by the framework
 @PropertySource({"classpath:service.properties","classpath:swagger.properties"})
@ComponentScan(basePackages = {"com.learning.api.controller",
    "com.test.api.service",
    "com.test.email.common",
    "com.test.api.config",
    "com.test.common"})
@EnableTransactionManagement
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.SpringMVCServerCodegen", date = "2016-03-01T00:10:36.598Z")
public class MVCConfig extends WebMvcConfigurerAdapter {
@Autowired
Environment env;
@Autowired
SimpleClientHttpRequestFactory httpClientFactory;

@Bean
ApiInfo apiInfo() {
    ApiInfo apiInfo = new ApiInfo(
            "Learning PI",
            "Welcome to Learning API 1.0.0",
            "1.0.0",
            "",
            "",
            "",
            "" );
    return apiInfo;
}

@Bean
public Docket customImplementation(){
    return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/");
    viewResolver.setSuffix(".jsp");
    return viewResolver; 
}

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.defaultContentType(MediaType.APPLICATION_JSON);
}

@Bean(name = "httpClientFactory")
public SimpleClientHttpRequestFactory getSimpleClientHttpRequestFactory() {
    SimpleClientHttpRequestFactory scrf = new SimpleClientHttpRequestFactory();
    scrf.setConnectTimeout(8000);
    scrf.setReadTimeout(8000);
    return scrf;
}

@Bean(name = "restTemplate")
@DependsOn("httpClientFactory")
public RestTemplate getRestTemplate() {
    return new RestTemplate(httpClientFactory);
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/index.html")
            .addResourceLocations("/");
    if (!registry.hasMappingForPattern("/webjars/**")) {
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    if (!registry.hasMappingForPattern("/**")) {
        registry.addResourceHandler("/**").addResourceLocations(RESOURCE_LOCATIONS);
    }
}

@Bean(name = "documentationController")
public JSONDocController docController() {
    JSONDocController jsonDocController = new JSONDocController("1.0", "http://localhost:8080/api", Arrays.asList("com.learning.api.controller"));
    jsonDocController.setPlaygroundEnabled(true);
    jsonDocController.setDisplayMethodAs(JSONDoc.MethodDisplay.URI);
    return jsonDocController;
}

//TODO:what's this?
@Bean(name="simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
    env.getProperty("prop.common");
    SimpleMappingExceptionResolver r =
            new SimpleMappingExceptionResolver();

    Properties mappings = new Properties();
    mappings.setProperty("DatabaseException", "databaseError");
    mappings.setProperty("InvalidCreditCardException", "creditCardError");

    r.setExceptionMappings(mappings);  // None by default
    r.setDefaultErrorView("error");    // No default
    r.setExceptionAttribute("ex");     // Default is "exception"
    r.setWarnLogCategory("example.MvcLogger");     // No default
    return r;
}
@Bean(name = "multipartResolver")
public CommonsMultipartResolver commonsMultipartResolver(){
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(1999904800);
    return multipartResolver;
}
private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
        "classpath:/META-INF/resources/", "classpath:/resources/",
        "classpath:/static/", "classpath:/public/" };

private static final String[] RESOURCE_LOCATIONS;
static {
    RESOURCE_LOCATIONS = new String[CLASSPATH_RESOURCE_LOCATIONS.length
            + SERVLET_RESOURCE_LOCATIONS.length];
    System.arraycopy(SERVLET_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS, 0,
            SERVLET_RESOURCE_LOCATIONS.length);
    System.arraycopy(CLASSPATH_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS,
            SERVLET_RESOURCE_LOCATIONS.length, CLASSPATH_RESOURCE_LOCATIONS.length);
}

private static final String[] STATIC_INDEX_HTML_RESOURCES;
static {
    STATIC_INDEX_HTML_RESOURCES = new String[RESOURCE_LOCATIONS.length];
    for (int i = 0; i < STATIC_INDEX_HTML_RESOURCES.length; i++) {
        STATIC_INDEX_HTML_RESOURCES[i] = RESOURCE_LOCATIONS[i] + "index.html";
    }
}

}

我的一个控制器:

@Controller
@Api(value = "students", description = "Student API")
@RequestMapping("/api/v1/students")
public class StudentController {
@Autowired
private CommonService commonService;
@Autowired
private StudentService studentService;

@ResponseBody
@RequestMapping(value="/{studentId}/scores/statistics",method = RequestMethod.GET)
    public ScoreStatisticsViewModel getScoreStatistics(@PathVariable String studentId,@RequestParam String startDate,@RequestParam String endDate){
        return commonService.getScoreStatisticsViewModel(studentId,startDate,endDate,null,null,null,null);
    }
}

更新堆栈跟踪:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'null' not supported
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:231) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:349) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:296) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:56) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:299) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1120) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:932) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) [spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) [spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) [spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) [catalina.jar:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.30]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.30]
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:178) [spring-orm-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.30]
at com.learninggenie.api.logging.LoggerFilter.doFilter(LoggerFilter.java:40) [classes/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.30]
at com.learninggenie.api.config.SimpleCORSFilter.doFilter(SimpleCORSFilter.java:23) [classes/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.30]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) [catalina.jar:8.0.30]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.30]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [catalina.jar:8.0.30]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [catalina.jar:8.0.30]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.30]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [catalina.jar:8.0.30]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.30]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) [catalina.jar:8.0.30]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) [tomcat-coyote.jar:8.0.30]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) [tomcat-coyote.jar:8.0.30]
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500) [tomcat-coyote.jar:8.0.30]
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489) [tomcat-coyote.jar:8.0.30]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.30]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]

如果您将每个控制器明确设置为 "produce" JSON,它应该可以工作。我确信在配置中也有办法做到这一点,但我一直认为明确设置生产和消费是最佳做法。

@RequestMapping(value="/{studentId}/scores/statistics",
            produces = {"application/json"},
            consumes = {"application/json"},
            method = RequestMethod.GET)