2016-02-21 1 views
1

У меня возникла проблема с сериализацией Джексона для моего объекта LoginResp. Он показывает мнеНевозможно создать ответ REST с помощью @Proxy и Jackson

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"]-..... 

Я пытаюсь повторить тот же сценарий, и используя тот же код, как указано в this link. Но получить вышеуказанную ошибку. Пожалуйста, помогите, поскольку я просто хочу записать значение моего «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> 

Мой LoginResp класс

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

} 

ответ

0

Прежде всего, не используют метод System.out.println на на стороне сервера. Всегда используйте некоторую утилиту ведения журнала, такую ​​как log4j slf4j или любой другой, который вы, возможно, знаете. Однако это очень маловероятно, причина для вашей проблемы. Судя по ошибке, у вас есть некоторая круговая ссылка с вашей конфигурацией ведения журнала. Установите точку останова в контроллере, чтобы увидеть, добираетесь ли вы до того, как произошла ошибка или произошла ошибка даже до того, как вы попытаетесь вызвать ваш метод. В любом случае я предполагаю, что у вас проблема с настройкой протоколирования, и ваша проблема - результат этого, а не вашего кода, который, кажется, выглядит на первый взгляд, за исключением использования System.out.println.

+0

Thnks для вашего ввода и вы правы. Моя ошибка - cominn внутри блока try в строке "someJsonString = mapper.writeValueAsString (resp);" – Regal

+0

Я не использую какой-либо явный регистратор, но в тот момент, когда я использую @Scope, мой Джексон показывает эту ошибку для «java.util.logging». Как вы можете c..i'm использовать все, начиная с "mapper.disable (SerializationFeature.FAIL_ON_EMPTY_BEANS);" , "mapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY)", а также настраиваемый фильтр ... Но никакой эффект – Regal

+0

попытается удалить строку "mapper.setVisibility (PropertyAccessor.FIELD, Visibility.ANY);" и "System.out.println (e.getMessage()); –

0

Я решил.

Наблюдение: Джексон не может преобразовать/процесс прокси-объект в строке

someJsonString = mapper.writeValueAsString(resp); в Ьгу блоке.

Решение: Объекты прокси-сервера обернуты вокруг фактического объекта. Я обращаюсь к фактическому объекту за прокси-сервером, используя указанную функцию here.

Эффект: Теперь нет необходимости настраивать свой 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); 

больше не требуется.

Смежные вопросы