2016-01-19 24 views
0

我正在嘗試Serialize我的@Service用於將@SessionAttribute添加到我的@Controller我的Spring MVC自動裝配代碼和@SessionAttribute有什麼問題?

現在的問題有@Autowired@RepositoryService類中加載的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); 
} 
+0

你爲什麼要在會話中存儲@Service? –

+0

@AlanHay嗨,只是我想'清除'的網絡形式,'服務'已被分配給它使用'@ ModelAttribute',所以當我閱讀時,我必須使用'SessionAttribute'除了'SesstionStatus'以將其設置爲完成會話以將modelattribute設置爲清除,因此表單在提交後不會再存儲數據,請更正我的問題? – Jason4Ever

回答

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())(如上)

通過這樣做這允許你的狀態(表單數據)被序列化,並且你的邏輯(權限庫)成爲Spring管理的無狀態單例。

另一方面,在您的實現中存在一個錯誤,您的Permissions組件不是線程安全的,因爲它將Web請求狀態存儲在私有「表單」字段中。由於這個組件是單身人士,所有的網絡請求都會嘗試覆蓋導致不可預知結果的表單值。

+0

謝謝,坦率地說,我並不是試圖將表單字段保存在我的「服務」組件中。反之亦然是正確的。 只需「我有一個表單,我想在成功提交表單後清除它的字段'值'。 '驗證後' 我的知識可能會混淆有關Spring MVC – Jason4Ever