Spring Boot 休息服务 |不支持请求方法“GET”

Posted

技术标签:

【中文标题】Spring Boot 休息服务 |不支持请求方法“GET”【英文标题】:Spring Boot Rest Service | Request method 'GET' not supported 【发布时间】:2016-07-29 15:30:12 【问题描述】:

我使用 spring boot 做了一个 hello world rest 服务。 我可以通过独立的 java 程序调用该服务。我也可以通过Advanced Rest Client Chrome 插件调用它。

但是当我尝试使用 jQuery AJAX 通过独立的 html 页面点击它时,我收到了错误

WARN 3748 --- [nio-9000-exec-2] o.s.web.servlet.PageNotFound:不支持请求方法“GET”

感谢任何帮助。

PS:我假设我可以使用其他方式调用 WebService 模式,所以控制器很好。但我的方式有些不对劲 从 HTML 调用它。

HTML 页面如下:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">
  <title>Client</title>
  <script type="text/javascript" src="jquery-2.2.3.js">
  </script>
  <script type="text/javascript">
    $(document).ready(function() 
      $("#Submit").click(function() 
        var input = 
          "name": $("#name").val(),
          "language": $("#language").val()
        ;
        var inputStr = JSON.stringify(input);
        alert(inputStr);
        $.ajax(
          url: "http://localhost:9000/rest/greetMeObj/",
          method: "POST",
          data: inputStr,
          dataType: "jsonp",
          success: function(output)  // callback method for further manipulations
            var str = JSON.stringify(output);
            $("#output").text(data);
          ,
          error: function(data)  // if error occured
            $("#error").text(data);
          
        );

      );
    );
  </script>
</head>

<body>
  <div id="input">
    <label><b>Name:</b>
    </label>
    <input type="text" name="name" id="name"  title="Enter your name" />
    <br />
    <br />
    <label><b>Language:</b>
    </label>
    <select name="language" id="language" title="Select your language">
      <option value="en" label="English" selected="selected">English</option>
      <option value="fr" label="French">French</option>
      <option value="nl" label="Dutch">Dutch</option>
    </select>
    <br />
    <br />
    <button title="Submit" type="button" name="Submit" id="Submit" value="Submit" formaction="POST">Submit</button>
  </div>
  <div id="output"></div>
  <div id="error" style="color: red;"></div>
</body>

</html>

下面的弹簧控制器

@Controller
@RequestMapping("/rest/*")
public class GreetingController 

    private static final String TEMPLATE_EN = "Hello, %s!";
    private static final String TEMPLATE_FR = "Bonjour, %s!";
    private static final String TEMPLATE_NL = "Hallo, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping(value="/rest/greetMe", method= RequestMethod.GET)
    public @ResponseBody Greeting sayHello(
            @RequestParam(value = "name", required = false, defaultValue = "Stranger") String name,
            @RequestParam(value = "language", required = false, defaultValue = "en") String language) 
        return new Greeting(counter.incrementAndGet(), String.format(getTemplate(language), name));
    

    @RequestMapping(value="/rest/greetMeObj", method= RequestMethod.POST)
    public @ResponseBody Greeting sayHello(
            @RequestBody(required = true) Input input) 
        return new Greeting(counter.incrementAndGet(),
                String.format(getTemplate(input.getLanguage()), input.getName()));
    

    private String getTemplate(String language) 
        String template;
        switch (language) 
        case "nl":
        case "NL":
            template = TEMPLATE_NL;
            break;
        case "fr":
        case "FR":
            template = TEMPLATE_FR;
            break;
        case "en":
        case "EN":
        default:
            template = TEMPLATE_EN;
            break;
        
        return template;
    

【问题讨论】:

这只是一个WARN,可以忽略吗?还是这个警告会导致另一个错误? 显然你不能为跨域请求使用 jsonp 发帖 【参考方案1】:

我猜这里描述了解决方案:Why SpringMVC Request method 'GET' not supported?

RequestMapping 中的两个值必须相同。因此,对于每个值,您必须为 GET 定义一个,为 POST 定义一个。

@RequestMapping(value="/rest/greetMe", method= RequestMethod.GET)
public @ResponseBody Greeting sayHello(
        @RequestParam(value = "name", required = false, defaultValue = "Stranger") String name,
        @RequestParam(value = "language", required = false, defaultValue = "en") String language) 
    return new Greeting(counter.incrementAndGet(), String.format(getTemplate(language), name));


@RequestMapping(value="/rest/greetMe", method= RequestMethod.POST)
public @ResponseBody Greeting sayHello(
        @RequestBody(required = true) Input input) 
    return new Greeting(counter.incrementAndGet(),
            String.format(getTemplate(input.getLanguage()), input.getName()));

【讨论】:

【参考方案2】:

检查您的控制器,如果您已将这些调用中的任何一个映射到默认映射:

    @DeleteMapping()
    @PostMapping()
    @GetMapping()

它被映射到path="/"。请改成

    @DeleteMapping(path="/something")
    @PostMapping(path="/something")
    @GetMapping(path="/something")

【讨论】:

以上是关于Spring Boot 休息服务 |不支持请求方法“GET”的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 休息服务错误处理

不支持请求方法“OPTIONS”-Spring Boot 应用程序

XmlElement(name="custom_name") 在与休息服务集成的 Spring Boot 中不起作用

在 Spring Boot 中创建动态服务

请求方法'OPTIONS'不受支持 - Spring Boot Application

独立休息服务的Spring Boot安全性[重复]