【问题标题】:Getting "No message available" error with Spring Boot + REST applicationSpring Boot + REST 应用程序出现“无可用消息”错误
【发布时间】:2016-03-12 03:39:13
【问题描述】:

我已经创建了演示 Spring Boot 项目并实现了 Restful 服务,如下所示

@RestController
public class GreetingsController {
    @RequestMapping(value="/api/greetings", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> getGreetings(){
        return new ResponseEntity<String>("Hello World", HttpStatus.OK);
    }
}

当我尝试使用带有 URL“http://localhost:8080/api/greetings”作为请求方法 GET 的 Postman 工具调用服务时,我收到以下错误消息

{
  "timestamp": 1449495844177,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/api/greetings"
}

对于每个 Spring Boot 应用程序,我不必在 web.xml 中配置 Spring Dispatcher servlet。

有人可以帮我找出这里的缺失点吗?

【问题讨论】:

  • 控制器看起来不错,可能它没有被根应用程序类连接。你确定它正在被实例化/连接(添加一个带断点的构造函数)吗?包含控制器类的包是否在根应用程序包“下”(我犯过多次的常见错误)?

标签: java spring rest spring-mvc spring-boot


【解决方案1】:

你可能错过了@SpringBootApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

@SpringBootApplication 包括@ComponentScan,它会扫描它所在的包和所有子包。您的控制器可能不在其中任何一个中。

【讨论】:

  • 感谢卡恩的快速帮助。我没有在我的 spring-boot 类中注释 @ComponentScan
  • 很高兴为您提供帮助 :) 我相信您不需要使用 @ComponentScan 进行注释,因为 @SpringBootApplication 已经包含它
  • 这个答案对我不起作用。这种错误可能还有其他原因。截至目前,我的损坏代码位于:github.com/djangofan/maven-spring-boot-testing-example。希望我今天能弄清楚如何解决它。
  • 试试@SpringBootApplication(scanBasePackages = {"com.xxx.yyy"}) 这里com.xxx.yyy是基础包。你的控制器应该在这个包里面
  • @KasunKariyawasam 为什么我需要那个?它有效,但我想知道为什么我需要明确告诉 SpringBootApplication 我的控制器类在哪里。
【解决方案2】:

三种可能的解决方案:

1) 确保带有@Controller 的YourController.java 文件和带有@SpringBootApplication 的YourSpringBootFile.java 文件在同一个包中。

例如,这是错误的:

这是正确的方法:

所以你知道我在说什么,这是我的 WebController.java 文件:

@RestController
public class WebController {
private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping(value= "/hi", method = RequestMethod.GET)
    public @ResponseBody Greeting sayHello(
            @RequestParam(value = "name", required = false, defaultValue = "Stranger") String name) {
        System.out.println("Inside sayHello() of WebController.java");
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}

这是我的 JsonPostExampleProj1Application.java:

@SpringBootApplication
public class JsonPostExampleProj1Application {

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

2) 如果您希望控制器位于 YourSpringBootFile.java 包之外的不同包中,请按照以下说明操作 = Spring: Run multiple "SpringApplication.Run()" in application main method

3) 尝试在 Controller 类之上使用 @RestController 而不是 @Controller。

【讨论】:

  • 这对我有用:尝试在 Controller 类之上使用 RestController 而不是 Controller
  • Greeting类应该怎么看?
  • 你说的“应该怎么看”是什么意思?你的 GreetingsController 类就是我的 WebController 类。
【解决方案3】:

这可以帮助我的情况。

确保控制器的包名是 Spring 主方法包的派生(或子)包。

例如:

如果主方法包是com.company.demo.example,那么controller包应该是com.company.demo.example.controller(如果你指定了com.company.demo.controller这样的东西,它就不起作用了!)。

【讨论】:

    【解决方案4】:

    除了用@SpringBootApplication((scanBasePackages = "com.duwamish.x.y")注释SpringBoot入口点,以便在初始化时包含所有spring组件/bean,

    contextPath 也必须是正确的。如果应用部署到tomcat,应用名称为myapplication,见下图,

    $ ll /usr/local/apache-tomcat-8.0.42/webapps/
    total 179216
    12495017 drwxrwxrwx  17 urayagppd  NORD\Domain Users       578 Mar  8 11:59 ROOT
    12495019 drwxrwxrwx  55 urayagppd  NORD\Domain Users      1870 Mar  8 11:59 docs
    12495042 drwxrwxrwx   7 urayagppd  NORD\Domain Users       238 Mar  8 11:59 examples
    12495109 drwxrwxrwx   7 urayagppd  NORD\Domain Users       238 Mar  8 11:59 host-manager
    12495114 drwxrwxrwx   8 urayagppd  NORD\Domain Users       272 Mar  8 11:59 manager
    16169612 drwxr-xr-x   4 urayagppd  NORD\Domain Users       136 May  7 18:47 myapplication
    16169594 -rw-r--r--   1 urayagppd  NORD\Domain Users  45340041 May  7 18:47 myapplication.war
    

    那么 REST 端点将是 /myapplication/api/greetings

    但如果应用程序war部署为ROOT,则端点资源将仅为/api/greetings

    【讨论】:

      【解决方案5】:

      如果您单独使用@SpringBootApplication,请确保您的休息服务控制器在同一个包中,如下所示 -

      com.testSpring->SpringBootApplication class
      com.testSpring.controller->RestfulController classes
      com.testSpring.model->Model classes
      ..etc
      

      如果您使用@ComponentScan(basePackageClasses = UserController.class),请提及特定的控制器类名称。

      【讨论】:

        【解决方案6】:

        我刚遇到这个错误,上面的解决方案都不适合我,所以我添加了另一个可能你也可能错过的东西,确保你的方法上有注释 @ResponseBody

        @RequestMapping(value="/yourPath", method=RequestMethod.GET)
        @ResponseBody
        public String exampleMethod() {
        return "test";
        }
        

        【讨论】:

          【解决方案7】:

          在我的例子中,我通过功能区调用了错误的路径。

          @FeignClient(name = "currency-exchange")
          @RibbonClient(name = "currency-exchange")
          public interface CurrencyExchangeProxy {
          
              @GetMapping("/exchange/{from}/to/{to}")
              PairRateDto callForExchangeValue(@PathVariable("from") String fromValue, @PathVariable("to") String toValue);
          
          }
          

          远程currency-exchange 服务没有/exchange/{from}/to/{to} 路径的处理程序。

          所以对于不存在的 URL,我得到了 404,这与“没有可用的消息”是公平的,这很奇怪。

          【讨论】:

            【解决方案8】:

            其实你需要把Controller包和你的SpringBootApplication java文件(spring boot main java class)包含在同一路径下。

            com.abc | |---- @SpringBootApplication 主java类

            com.abc.controller | |---- @RestController 类

            【讨论】:

              【解决方案9】:

              对我来说,我有同样的错误,但我意识到我调用 api 的路径是问题所在。 如果我的应用程序名称是 demo,我必须调用 http://localhost:9090/AdminProducts 访问 AdminProducts, 不是http://localhost:9090/demo/AdminProducts。在tomcat中部署war后可以使用这个名字。

              【讨论】:

                【解决方案10】:

                如果“无可用消息”伴随 404,只需检查您的 http 请求,任何语法问题都可能是这种情况。

                至少我是在使用邮递员发帖时请求中的语法错误。

                【讨论】:

                  【解决方案11】:

                  你所有的包都应该在主包之后,

                  喜欢这个 com.example.demo.*(你所有的包)

                  【讨论】:

                    猜你喜欢
                    • 2021-12-18
                    • 1970-01-01
                    • 2016-11-07
                    • 2014-10-25
                    • 2021-05-18
                    • 2023-03-27
                    • 1970-01-01
                    • 2018-06-19
                    • 2015-08-08
                    相关资源
                    最近更新 更多