java - Controller 类级别的 Pathvariable 在 Spring Restful 上不起作用

标签 java spring rest spring-mvc path-variables

我有一个 Controller ,其中 Controller 级别映射为“/subjects/{subjectId}/lessons”,由于某种原因这是必需的

@RestController
@RequestMapping( value = "/subjects/{subjectId}/lessons",produces = { MediaType.APPLICATION_JSON_VALUE } )
public class LessonController {
    .......
    @RequestMapping( method = RequestMethod.GET )
    public ResponseEntity<Resources<Resource<Lesson>>> getAllSjubject(@PathVariable(value = "subjectId") int subjectId){        

        List<Lesson> lessonList = lessonService.getAllLessons(subjectId);
        Resources<Resource<Lesson>> resource = this.lessonResourceAssembler.toLessonResourceList(lessonList);
        return new ResponseEntity<Resources<Resource<Lesson>>>(resource, HttpStatus.OK);
    }
}

请求时抛出异常

java.lang.IllegalArgumentException: Not enough variable values available to expand 'subjectId'
    at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:327)
    at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:230)
    at org.springframework.web.util.HierarchicalUriComponents$FullPathComponent.expand(HierarchicalUriComponents.java:685)
    at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:328)
    at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:47)
    at org.springframework.web.util.UriComponents.expand(UriComponents.java:163)
    at org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo(ControllerLinkBuilder.java:89)
    at org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo(ControllerLinkBuilder.java:69)
    at com.khaino.springrest.assembler.LessonResourceAssembler.toLessonResource(LessonResourceAssembler.java:31)
    at com.khaino.springrest.assembler.LessonResourceAssembler.toLessonResourceList(LessonResourceAssembler.java:44)
    at com.khaino.springrest.controller.LessonController.getAllSjubject(LessonController.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:111)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

但是当我将路径变量移动到下面的方法级别时,它工作正常。

@RequestMapping( value = "/subjects",produces = { MediaType.APPLICATION_JSON_VALUE } )
public class LessonController {

    ......

    @RequestMapping( value = "/{subjectId}/lessons", method = RequestMethod.GET )
    public ResponseEntity<Resources<Resource<Lesson>>> getAllSjubject(@PathVariable("subjectId") int subjectId){        

        List<Lesson> lessonList = lessonService.getAllLessons(subjectId);
        Resources<Resource<Lesson>> resource = this.lessonResourceAssembler.toLessonResourceList(lessonList);
        return new ResponseEntity<Resources<Resource<Lesson>>>(resource, HttpStatus.OK);
    }

    ....
}

我的代码有问题吗?可能是什么原因和解决方法?

最佳答案

您的映射在这两种情况下都有效,但根据您的堆栈跟踪,以下部分是问题的根源:

this.lessonResourceAssembler.toLessonResourceList(lessonList)

您正在创建一些超媒体链接,其中包含一些未展开的模板变量

已更新:使用此方法创建链接:

linkTo(methodOn(LessonController.class).getAllSjubject(42))
                .withRel(REL_SELF)

mehtodOnorg.springframework.hateoas.mvc.ControllerLinkBuilder 包中,确保你有正确的静态导入。

关于java - Controller 类级别的 Pathvariable 在 Spring Restful 上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33491932/

相关文章:

spring - 身份验证时Auth0:NoSuchMethodError

java - REST - 如何使用 Jersey 传递一个 long in 参数数组?

用于 Tomcat 的 REST Web 服务

java - hibernate 中的 saveOrUpdate() 不起作用,而是执行一个选择查询,该查询在程序中没有提到。 (使用spring+hibernate)

java - 如何将一个 bean 的构造函数参数传递给嵌套 bean

web-services - OData 和 REST Web 服务之间的区别

java - 用 Java 玩纸牌

java - 向 Sonarqube 添加 Java 代码格式化规则

java - 未找到 ManagedExecutorService

java - basicAck 不会从代理中删除消息 - RabbitMQ