Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json springmvc@Scope代理bean&;杰克逊2_Json_Spring_Spring Mvc_Jackson - Fatal编程技术网

Json springmvc@Scope代理bean&;杰克逊2

Json springmvc@Scope代理bean&;杰克逊2,json,spring,spring-mvc,jackson,Json,Spring,Spring Mvc,Jackson,我正在尝试开发一个小型的SpringMVC应用程序,我希望用户对象从每个会话开始就初始化 我有用户类 @Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class MyUser implements User { // private fields // getters and setters public void fillByName(Str

我正在尝试开发一个小型的SpringMVC应用程序,我希望用户对象从每个会话开始就初始化

我有用户类

@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);
    }

}
我想在Spring Security识别出拦截器类中的用户后初始化MyUser对象(顺便说一句,这是一个好的实践吗?)

所以,当控制器处理请求时,已经初始化了会话范围的用户类。但当我尝试用Jackson序列化MyUser对象时,它就是不起作用:

@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对象getter在Controller类中工作得很好,但Jackson-没有

当我从用户对象中删除@Scope注释时,序列化开始工作

显然,作用域代理bean和单例控制器类是问题所在

但我怎样才能修复它呢

--

更新

看来我是第一个遇到这个的人:)
也许是糟糕的建筑?我应该在控制器中创建MyUser类的新实例吗?通常的做法是什么?

我可以想到的一种方法是添加另一个包装器:

@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())

原因是您的
proxyMode
设置为
TARGET\u CLASS
,这指示Spring为您的类创建基于类的代理(本质上是一个实现原始类接口的新类,但可能与
ObjectMapper
将对象转换为字符串的方式不兼容)

您可以通过告诉
ObjectMapper
在使用
writer编写对象时要使用哪些类签名来解决此问题,例如:

mapper.writerFor(User.class).writeValueAsString(user)
或者,如果您已经有了自定义编写器,请使用
for class
,如下所示:

writer.forClass(User.class).writeValueAsString(user)
writer.forClass(User.class).writeValueAsString(user)