带有Controller的简单Spring Boot项目中的"循环视图路径"

log*_*off 9 rest spring-boot

我有一个简单的Spring Boot项目和这个Gradle构建文件:

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
apply plugin: 'war'

sourceCompatibility = 1.7
targetCompatibility = 1.7

version = '1.0'

buildscript {
    ext {
        springBootVersion = '1.1.9.RELEASE'
    }
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.9.RELEASE")
    }
}

jar {
    manifest {
        attributes 'Implementation-Title': 'Potlatch Server', 'Implementation-Version': version
    }
}

war {
    baseName = 'gs-convert-jar-to-war'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
    maven { url "http://repo.spring.io/libs-snapshot" }
    maven { url "http://maven.springframework.org/milestone" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")

    compile("org.springframework.boot:spring-boot-starter-tomcat:${springBootVersion}")

    compile("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")
    compile("org.springframework.boot:spring-boot-starter-aop:${springBootVersion}")
    compile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")
    compile("org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}")

    compile("org.springframework.data:spring-data-rest-webmvc")

    compile("org.hsqldb:hsqldb")

    compile("com.google.guava:guava:17.0")
    compile("org.apache.httpcomponents:httpclient:4.3.4")
    compile("com.squareup.retrofit:retrofit:1.6.0")
    compile("commons-io:commons-io:2.4")

    testCompile("junit:junit")
}
Run Code Online (Sandbox Code Playgroud)

此应用程序文件:

@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application extends RepositoryRestMvcConfiguration {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public ObjectMapper halObjectMapper() {
        return new ResourcesMapper();
    }

}
Run Code Online (Sandbox Code Playgroud)

这个控制器接口:

public interface Controller {

    @RequestMapping(value = "/test", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public void test();
}
Run Code Online (Sandbox Code Playgroud)

而这个控制器实现:

@Controller
public class ControllerImpl implements Controller {

    @Override
    public void test() {
    }

}
Run Code Online (Sandbox Code Playgroud)

应用程序启动时没有错误,但是当发送HTTP GET请求时http://localhost:8080/test,我收到此错误:

javax.servlet.ServletException: Circular view path [test]: would dispatch back to the current handler URL [/test] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
    at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:263)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:186)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:280)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:90)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

我的错是什么?

如何修改我的简单项目以避免此错误?

And*_*son 31

您已将控制器方法注释为生成JSON,但它返回void.您可能希望使用该方法注释@ResponseBody并更改其返回类型,以允许您返回要包含在响应中的JSON的对象表示形式

  • 是的,返回void是圆形视图路径错误的原因.在没有`@ ResponseBody`的情况下,Spring MVC认为你想渲染一个视图.void返回类型意味着视图名称为null,因此它使用由请求的路径确定的默认值.在这种情况下,`test`会导致你的`test()`控制器方法被再次调用. (4认同)
  • 只是确切的解决方案,谢谢@andy。此外,我发现使用public @ResponseBody void test();是合法的签名,响应是没有身体的200 OK。大! (2认同)

azi*_*sal 29

您可以@RestController在Spring Boot项目中使用而不是@Controller注释.这样,@ResponseBody即使方法没有返回任何值,也不必在方法中使用注释.

  • 感谢您的解决方案!这个对我有用) (2认同)