我的Spring MVC自动装配代码和@SessionAttribute有什么问题?

时间:2016-01-19 12:36:13

标签: spring spring-mvc spring-security spring-boot

我正在尝试Serialize我的@Service@SessionAttribute添加到我的@Controller

现在问题是@Autowired类中有@Repository Service用于加载repositoy,并且在Deserializing服务对象之后不会加载。虽然我使用SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);但没有解决问题。

package jas;

@Configuration
@SpringBootApplication 
@ComponentScan
public class BackofficeApplication {

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

控制器

package jas.controllers;

@Controller
@SessionAttributes({"permissionsForm"})
public class PermissionsController {
    @Autowired
    @Qualifier("permissionValidator")
    private Validator validator;

    @Autowired
    private Permissions permissionsAdd;

    @InitBinder
    private void initBinber(WebDataBinder binder){
        binder.setValidator(validator);
    }

    @ModelAttribute("viewTemplate")
    public String createviewTemplate(){
        return "permissions-add";
    }

    @ModelAttribute("permissionsForm")
    public Permissions permissionsAdd(){
        return permissionsAdd;
    }

    @RequestMapping(value = "/permissions:add", method=RequestMethod.GET)
    private String addGet(Model model) {
        return "welcome";
    }
}

服务

package jas.beans.services;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import jas.beans.Role;
import jas.beans.repo.PermissionsRepository;

@Component
public class Permissions implements Serializable{ 
    /**
     * 
     */
    private static final long serialVersionUID = -495480557873675142L;

    @Autowired
    private static PermissionsRepository repository;

    // Form
    private HashMap form = new HashMap();

    public Permissions(){
    }

    public PermissionsRepository getRepository(){
        if(this.repository == null){
                    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 
        }

        return this.repository;
    }

    public Iterable<Role> getAll(){
        return this.getRepository().findAll();
    }
}

存储库

package jas.beans.repo;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import jas.beans.Role;

@Component
public interface PermissionsRepository extends CrudRepository<Role, Long>{

    @Query("SELECT r FROM Role r WHERE r.username = ?1")
    Role findbyUsername(String username);
}

1 个答案:

答案 0 :(得分:1)

您无法解释为什么您需要在会话中保留表单,但假设您这样做,并且您不能简单地在“addGet”中发送值。请求,例如

private final PermissionsRepository permissionsRepository;

@Autowired
public PermissionsController(PermissionsRepository permissionsRepository) {
    this.permissionsRepository = permissionsRepository;
}

@RequestMapping(value = "/permissions:add", method=RequestMethod.GET)
private String addGet(@RequestParameter String username, Model model) {
    return permissionsRepository.findByUsername(username);
}

所以,假设这里不可能是另一个解决方案:

为了获得序列化的权限,您需要将表单与服务分开(当您将数据与业务逻辑分开时,这也将导致更简洁的实现。)

  1. 更改PermissionsForm对象的权限,该对象是一个存储HTTP请求属性的简单java bean。即不是组件,没有依赖
  2. 将您的PermissionsRepository自动装入您的控制器(如上所述)
  3. 在您的控制器方法中调用permissionsRepository.findbyUsername(permissionsForm.getUsername())(如上所述)
  4. 通过这样做,您可以将您的状态(表单数据)序列化,并将您的逻辑(权限存储库)作为Spring管理的无状态单例。

    顺便说一句,您的实现中存在一个错误,您的权限组件不是线程安全的,因为它以私有形式存储Web请求状态。领域。由于此组件是单个组件,因此所有Web请求都会尝试覆盖表单值,从而导致不可预测的结果。