【问题标题】:Spring boot - setters on session scoped component not working from singleton service - fields are nullSpring Boot - 会话范围组件上的设置器无法从单例服务工作 - 字段为空
【发布时间】:2018-08-13 12:14:35
【问题描述】:

我在 Spring Boot 的 REST 控制器后面有一个简单的服务。该服务是一个单例(默认情况下),我正在自动装配一个会话范围的 bean 组件,用于存储会话首选项信息并尝试从服务中填充其值。我在自动装配组件上调用 setter,但我设置的字段保持为空并且没有更改。

尝试过在 bean 上使用和不使用 Lombok;也有和没有在 FooPref 上实现 Serializable;还将属性从 FooPrefs 复制到另一个 DTO 并返回它;还通过@Autowired 注入以及使用@Inject 进行构造函数注入。在所有这些情况下,这些字段都保持为空。

使用 spring-boot-starter-web 运行 Spring Boot (spring-boot-starter-parent) 1.5.6.RELEASE,Java 8。

会话范围的组件:

@Component
@SessionScope(proxyMode = ScopedProxyMode.TARGET_CLASS)
@Data
@NoArgsConstructor
public class FooPrefs implements Serializable {
    private String errorMessage;
    private String email;
    private String firstName;
    private String lastName;
}

REST 控制器:

@RestController
@RequestMapping("/api/foo")
public class FooController {

    @Autowired
    private FooPrefs fooPrefs;

    private final FooService fooService;

    @Inject
    public FooController(FooService fooService) {
        this.fooService = fooService;
    }

    @PostMapping(value = "/prefs", consumes = "application/json", produces = "application/json")
    public FooPrefs updatePrefs(@RequestBody Person person) {
        fooService.updatePrefs(person);

        // These checks are evaluating to true
        if (fooPrefs.getEmail() == null) {
            LOGGER.error("Email is null!!");
        }
        if (fooPrefs.getFirstName() == null) {
            LOGGER.error("First Name is null!!");
        }
        if (fooPrefs.getFirstName() == null) {
            LOGGER.error("First Name is null!!");
        }
        return fooPrefs;
    }
}

服务:

@Service
@Scope(value = "singleton")
@Transactional(readOnly = true)
public class FooService {

    @Autowired
    private FooPrefs fooPrefs;

    @Inject
    public FooService(FooRepository fooRepository) {
        this.fooRepository = fooRepository;
    }

    public void updatePrefs(Person person) {
        fooRepository.updatePerson(person);

        //the fields below appear to getting set correctly while debugging in the scope of this method call but after method return, all values on fooPrefs are null
        fooPrefs.setEmail(person.getEmail());
        fooPrefs.setFirstName(person.getFirstName());
        fooPrefs.setLastName(person.getLastName());
    }
}

【问题讨论】:

    标签: spring-boot proxy cglib session-scope


    【解决方案1】:

    我发现了我的问题。字段被添加到我的 FooPrefs 会话管理对象中并破坏了我的客户端。设置器实际上正在工作并被一些错误处理代码取消。

    以下修改修复了 JSON 序列化问题:

    会话范围的组件(无变化)

    新的 Dto

    @Data
    @NoArgsConstructor
    public class FooPrefsDto {
        private String errorMessage;
        private String email;
        private String firstName;
        private String lastName;
    }
    

    控制器(更新)

    @RestController
    @RequestMapping("/api/foo")
    public class FooController {
    
        private final FooService fooService;
    
        @Inject
        public FooController(FooService fooService) {
            this.fooService = fooService;
        }
    
        @PostMapping(value = "/prefs", consumes = "application/json", produces = "application/json")
        public FooPrefsDto updatePrefs(@RequestBody Person person) {
            FooPrefsDto result = fooService.updatePrefs(person);
    
            // results coming back correctly now
            if (result.getEmail() == null) {
                LOGGER.error("Email is null!!");
            }
            if (result.getFirstName() == null) {
                LOGGER.error("First Name is null!!");
            }
            if (result.getFirstName() == null) {
                LOGGER.error("First Name is null!!");
            }
            return result;
        }
    }
    

    服务(更新)

    @Service
    @Scope(value = "singleton")
    @Transactional(readOnly = true)
    public class FooService {
    
        @Autowired
        private FooPrefs fooPrefs;
    
        @Inject
        public FooService(FooRepository fooRepository) {
            this.fooRepository = fooRepository;
        }
    
        public FooPrefsDto updatePrefs(Person person) {
            fooRepository.updatePerson(person);
    
            //the fields below appear to getting set correctly while debugging in the scope of this method call but after method return, all values on fooPrefs are null
            fooPrefs.setEmail(person.getEmail());
            fooPrefs.setFirstName(person.getFirstName());
            fooPrefs.setLastName(person.getLastName());
            return getFooPrefsDto();
        }
    
        private FooPrefsDto getFooPrefsDto() {
            FooPrefsDto retDto = new FooPrefsDto();
            retDto.setEmail(fooPrefs.getEmail());
            retDto.setLastName(fooPrefs.getLastName());
            retDto.setFirstName(fooPrefs.getFirstName());
            return retDto;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 2010-12-17
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多