无法使用 @Proxy 和 Jackson 创建 REST 响应



我的 LoginResp 对象的杰克逊序列化遇到了问题。它向我展示了

Infinite recursion (StackOverflowError) (through reference chain: java.util.logging.LogManager["systemContext"]->java.util.logging.SystemLoggerContext["namedLoggers"]->java.util.Hashtable["global"]->java.util.logging.LoggerWeakRef["referent"]->java.util.logging.Logger["manager"]->java.util.logging.LogManager["systemContext"]->java.util.logging.SystemLoggerContext["namedLoggers"]->java.util.Hashtable["global"]->java.util.logging.LoggerWeakRef["referent"]->java.util.logging.Logger["manager"]->java.util.logging.LogManager["systemContext"]->java.util.logging.SystemLoggerContext["namedLoggers"]->java.util.Hashtable["global"]->java.util.logging.LoggerWeakRef["referent"]-.....

我正在尝试复制相同的场景并使用相同的代码,如此链接所述。但是得到上述错误。请帮忙,因为我只是想将我的"resp"bean的值写入我的"someJsonString"变量。提前谢谢。

这些是我的依赖

关系
<properties>
    <servlet-api-version>3.1.0</servlet-api-version>
    <spring-webmvc-version>4.2.4.RELEASE</spring-webmvc-version>
    <jackson-version>2.6.4</jackson-version>
</properties>
<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>${servlet-api-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring-webmvc-version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

我的登录回复类

package my.beans.resp;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class LoginResp {
private String username;
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
}

我的 REST 控制器

package my.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import my.beans.req.LoginReqB;
import my.beans.resp.LoginResp;
@RestController
@RequestMapping(path = "/login")
public class LoginC {
@Autowired
private LoginResp resp;
@RequestMapping(method = RequestMethod.POST)
public String authenticateUserLogin(@RequestBody LoginReqB request) {
    resp.setUsername("abc");
    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    SimpleFilterProvider filterP = new SimpleFilterProvider().addFilter("loginResp",
            SimpleBeanPropertyFilter.filterOutAllExcept("username"));
    mapper.setFilterProvider(filterP);
    String someJsonString = "";
    try {
        someJsonString = mapper.writeValueAsString(resp);
    } catch (JsonProcessingException e) {
        System.out.println(e.getMessage());
    }
    return someJsonString;
}
}

我解决了。

观察:杰克逊无法在行转换/处理代理对象

someJsonString = mapper.writeValueAsString(resp);在尝试块中。

解决方案:由于代理对象环绕在实际对象周围。我正在使用此处提到的函数访问代理背后的实际对象。

效果:现在,不需要自定义我的ObjectMapper,即

ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
SimpleFilterProvider filterP = new SimpleFilterProvider().addFilter("loginResp",
        SimpleBeanPropertyFilter.filterOutAllExcept("username"));
mapper.setFilterProvider(filterP);

不再需要。

首先,不要在服务器端使用 System.out.println 方法。始终使用一些日志记录实用程序,例如log4j slf4j或您可能知道的任何其他实用程序。但是,这不太可能成为您问题的原因。从错误来看,您的日志记录配置有一些循环引用。在控制器中设置断点,以查看是在错误发生之前到达该断点,还是在尝试调用方法之前发生错误。无论如何,我的猜测是你有日志记录配置问题,你的问题是它的结果,而不是你的代码,乍一看似乎还可以,除了System.out.println的使用。

最新更新