2015-04-03 5 views
4

Я пытаюсь разработать небольшое приложение Spring MVC, где я хотел бы, чтобы объект User инициализировался с начала каждого сеанса.Spring MVC @Scope proxy bean & Jackson 2

У меня есть класс пользователя

@Component 
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 
public class MyUser implements User { 

    // private fields 
    // getters and setters 


    public void fillByName(String username) { 
     userDao.select(username); 
    } 

} 

И я хочу, чтобы инициализировать объект MyUser раз Spring Security распознает пользователя, в перехватчик класса (Btw, это хорошая практика?)

public class AppInterceptor extends HandlerInterceptorAdapter { 

    @Autowired 
    MyUser user; 

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 

     Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 

     if (!(auth instanceof AnonymousAuthenticationToken)) { 
      user.fillByName(auth.getName()); 
     } 

     return true; 
    } 
} 

Итак, когда контроллер обрабатывает запрос, уже есть инициализированный класс пользователя, ограниченный сеансом. Но когда я пытаюсь сериализовать объект MyUser с Джексоном, он просто doesnt't работы:

@RequestMapping("/") 
    public String launchApp(ModelMap model) { 

     ObjectMapper mapper = new ObjectMapper(); 

     try { 
      System.out.println(user.getUsername()); // Works good! 
      model.addAttribute("user", mapper.writeValueAsString(user)); // Doesn't work 
     } catch (JsonProcessingException e) { 
      // @todo log an error 
     } 

     return "app/base"; 
    } 

Как вы можете видеть, объект MyUser добытчики хорошо работать из класса контроллера, но Джексон - нет.

Когда я удаляю аннотацию @Scope от объекта User, сериализация Джексона начинает работать.

Очевидно, контекстный прокси-боб и синглтон класс контроллера является проблемой

Но как я могу это исправить?

-

UPDATE

Похоже, я первый, кто сталкивался с этим :) Может быть, это плохая архитектура? Должен ли я создать новый экземпляр класса MyUser в контроллере? Какова распространенная практика?

ответ

2

Один из способов, что я могу думать о том, чтобы добавить еще одну обертку:

@Component 
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 
public class MyScopedUser implements User { 

    private MyUser myUser; 
    // private fields 
    // getters and setters 


    public void fillByName(String username) { 
     userDao.select(username); 
    } 

    public MyUser getMyUser() { 
     return this.myUser; 
    } 
} 

Так что теперь ваш MyScopedUser является областью действия прокси, но пользователь ядро ​​представляет собой обычный класс. Вы можете получить пользователя и маршал позже:

mapper.writeValueAsString(scopeUser.getMyUser()) 
Смежные вопросы