错误405:不允许在DELETE和PUT上使用该方法。

4
我按照这个 Spring教程 实现了一切,一切都很顺利。然后,我决定添加删除修改功能。我已经实现了它们,但是当我尝试使用它们时,我得到了以下错误:

{"status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/demo/delete"}

{"status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/demo/modify"}

我执行的命令:

curl localhost:8080/demo/delete -d name=First

curl localhost:8080/demo/modify -d name=First -d email=abc@gmail.com

//if the name doesn't exist in both methods, it will return "Nonexistent user!"

以下是MainController.java的代码:
package com.example.accessingdatamysql;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller 
@RequestMapping(path="/demo") 
public class MainController {
    @Autowired 
    private UserRepository userRepository;

    @PostMapping(path="/add") 
    public @ResponseBody String addNewUser (@RequestParam String name, 
           @RequestParam String email) {

        User n = new User();
        n.setName(name);
        n.setEmail(email);
        userRepository.save(n);
        return "Saved\n";
    }

    @GetMapping(path="/all")
    public @ResponseBody Iterable<User> getAllUsers() {
        return userRepository.findAll();
    }

    /* ----------------- NEW METHODS THAT I'VE CREATED ----------------- */

    @DeleteMapping(path="/delete")
    public String delete(@RequestParam String name) throws Exception {
        if(userRepository.findByName(name).equals(null)) {
            System.out.println("Nonexistent user!\n");
        }
        userRepository.deleteByName(name);
        return "User successfully deleted!\n";
    }

    @PutMapping(path="/modify")
    public String modify(@RequestParam String name, @RequestParam String email) throws Exception {
        if(userRepository.findByName(name).equals(null)) {
            System.out.println("Nonexistent user!\n");
        }

        userRepository.deleteByName(name);
        User n = new User();
        n.setName(name);
        n.setEmail(email);
        userRepository.save(n);
        return "User successfully modified!\n";
    }
}

User.java

package com.example.accessingdatamysql;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;

    private String name;

    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

UserRepository.java

package com.example.accessingdatamysql;

import org.springframework.data.repository.CrudRepository;

import com.example.accessingdatamysql.User;

public interface UserRepository extends CrudRepository<User, Integer> {

    public User findByName(String name);
    public void deleteByName(String name);
}

我不知道这里发生了什么。我已经搜索了其他类似的问题,但没有一个可以解决我的问题。

3个回答

2
您正在使用POST方法而不是DELETE方法来执行/demo/delete的调用,并且在/demo/modify中使用PUT方法。请注意修改。
{"status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/demo/delete"}

{"status":405,"error":"Method Not Allowed","message":"Request method 'POST' not supported","path":"/demo/modify"}

您没有展示如何执行那些失败的调用,但是例如,如果您使用一个GUI客户端如Postman来模拟这些调用,请确保选择了正确的HTTP方法。并且,如果您在终端中使用curl库,请注意所设置的方法:

curl -X "DELETE" http://your.url/demo/delete ...

curl -X "PUT" http://your.url/demo/modify ...

嗨,谢谢你的回答!现在这些方法正在工作,但是它们返回了错误404未找到,你知道为什么吗?另外,我已经在我的问题中添加了我正在执行的命令(我正在使用curl)。 - IncredibleCoding
欢迎!不过您应该开一个新的问题,来解决您在解决初始问题后遇到的问题。 - Dez

2
在遵循@Dez的答案后,问题得到了解决,但我还遇到了其他错误:
“当前线程没有实际事务可用的EntityManager - 无法可靠地处理'persist'调用”
我通过在MainController类的DELETE和PUT方法上添加@Transactional来解决它:
@DeleteMapping(path="/delete")
@Transactional //added
public void delete(@RequestParam String name) throws Exception { (...) }

@PutMapping(path="/modify")
@Transactional //added
public void modify(@RequestParam String name, @RequestParam String email) throws Exception { (...) }

并修改了异常抛出条件,该条件始终返回false

if(userRepository.findByName(name).equals(null)) {
     throw new Exception("Nonexistent user!");
}

to

if(userRepository.findByName(name) == null) {
     throw new Exception("Nonexistent user!");
}

0
这是 @DeleteMapping@PutMapping 的工作原理。这些注释是 @RequestMapping 的快捷方式,其 method 属性分别固定为 DELETEPUT。要允许一个端点使用多个 HTTP 方法,您应该明确列出它们:
@RequestMapping(path = "/modify", method = { RequestMethod.DELETE, RequestMethod.POST })
public String modify(...){
   ...
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接