微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Spring Boot 的 @RestController 注释使用的方法中使用带有参数的构造函数来创建请求处理程序

如何解决如何在 Spring Boot 的 @RestController 注释使用的方法中使用带有参数的构造函数来创建请求处理程序

我买了这本新书,试图快速学习 Spring Boot。它开始得很好,我轻松地创建了一个 REST API。但是后来我们添加了 CrudRepository,我看到了书中描述的代码问题。此外,没有代码可供下载,因为作者从 Oreily 的 git repo 中删除了它以修复某些问题...

问题是,如果我尝试按照书中描述的方式构建代码(没有认构造函数),我会收到一个 Java 错误,抱怨没有认构造函数。如果我添加一个认构造函数,它会构建,但 Spring 使用它而不是新构造函数,这需要传递一个参数。所以当我实际调用 API 时,就像我调用 /coffees 端点一样,我得到一个 java.lang.NullPointerException: null

那么 Spring 应该如何知道使用哪个构造函数,以及它如何为这个参数传递值

这是控制器:

package com.bw.restdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/coffees")
class RestAPIDemoController {
    private final CoffeeRepository coffeeRepository;
    
    public RestAPIDemoController(CoffeeRepository coffeeRepository) {
        this.coffeeRepository = coffeeRepository;
        
        this.coffeeRepository.saveAll(List.of(
                new Coffee("Cafe Cereza"),new Coffee("Freedom Fuel"),new Coffee("Cold Brew"),new Coffee("Sumatra")
                ));
    }
    public RestAPIDemoController() {
        this.coffeeRepository = null; 
    }; 
    
    //@RequestMapping(value = "/coffees",method = RequestMethod.GET)
    @GetMapping
    Iterable<Coffee> getCoffees() {
        return coffeeRepository.findAll();
    }
    
    @GetMapping("/{id}")
    Optional<Coffee> getCoffeeById(@PathVariable String id) {
        return coffeeRepository.findById(id); 
    }
    
    @PostMapping
    Coffee postCoffee(@RequestBody Coffee coffee) {
        return coffeeRepository.save(coffee); 
    }
    
    @PutMapping("/{id}")
    ResponseEntity<Coffee> putCoffee(@PathVariable String id,@RequestBody Coffee coffee) {
        return (!coffeeRepository.existsById(id)) 
                ? new ResponseEntity<>(coffeeRepository.save(coffee),HttpStatus.CREATED) 
                : new ResponseEntity<>(coffeeRepository.save(coffee),HttpStatus.OK);
    }
    
    @DeleteMapping("/{id}")
    void deleteCoffee(@PathVariable String id) {
        coffeeRepository.deleteById(id); 
    }
}

这里是我定义接口的地方:

package com.bw.restdemo;

import org.springframework.data.repository.CrudRepository;

interface CoffeeRepository extends CrudRepository<Coffee,String> {
    
}

这是主要课程——为塞在底部的课程道歉。

package com.bw.restdemo;

import java.util.UUID;

import javax.persistence.Entity;
import javax.persistence.Id;

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

@SpringBootApplication
public class RestDemoApplication {

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

}

@Entity
class Coffee {
    @Id
    private String id;
    private String name;
    
    public Coffee(String id,String name) {
        this.id = id;
        this.name = name;
    }
    public void setId(String id) {
        this.id = id; 
    }
    
    public Coffee(String name) {
        this(UUID.randomUUID().toString(),name); 
    }
    public String getId() {
        return id; 
    }
    public String getName() {
        return name; 
    }
    public void setName(String name) {
        this.name = name; 
    }
}

解决方法

CoffeeRepository 接口缺少@Repository 注解。

更新:

  • 在 CoffeeRepository 中添加 @Repository 注释
  • 从 RestAPIDemoController 中删除默认构造函数。
package com.bw.restdemo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
interface CoffeeRepository extends CrudRepository<Coffee,String> {
    
}

说明

在 spring 框架中,@Component 注解将一个 java 类标记为 bean,以便组件扫描机制可以将其拾取并拉入应用程序上下文中。由于 @Repository 作为 @Component 的特化,它还使带注释的类能够被发现并注册到应用程序上下文中。

详情请见 HowToDoInJava - @Repository annotation in Spring Boot

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。