2014-03-24 3 views
0

에서 돌아 JSON 응답을 필터링합니다. 어떻게 스프링 나머지 웹 서비스에서 반환 JSON 응답을 필터링하는 방법 스프링 나머지 웹 서비스

사용이 난 경우에만 이벤트 ID 만 이벤트 이름을 outout하는 데 필요한 customEvents를 호출 할 때. 구체적인 이벤트를 요청할 때 이벤트의 전체 세부 정보를 보내야합니다.

Class CustomEvent{ 

long id; 
String eventName; 
Account createdBy; 
Account modifiedBy; 
.. 


} 

Class Account{ 
long id; 
String fname; 
String lname; 
.... 

} 


@Controller 
public class CustomEventService 
{ 
    @RequestMapping("/customEvents") 
    public @ResponseBody List<CustomEvent> getCustomEventSummaries() {} 

    @RequestMapping("/customEvents/{eventId}") 
    public @ResponseBody CustomEvent getCustomEvent(@PathVariable("eventId") Long eventId) {} 
} 

어떻게하면됩니까? 나는 봄 3.1을 사용하고 있습니다. THER 내가 잭슨의 믹스 인 기능을 활용 모두 두 가지 솔루션 왼손 생각할 수

+0

MappingJacksonHttpMessageConverter 또는 MappingJackson2HttpMessageConverter를 사용하여 JSON에 매핑 할 때 Jackson을 사용하고 있습니까? – geoand

+0

getCustomEventSummaries()에서 Map <[ID_TYPE], [NAME_TYPE]>'을 반환하는 데 문제가 있습니까? 아니면'CustomEvent'의 다른 모든 속성을'null '로 만드십시오. –

+0

MappingJackson2HttpMessageConverter를 사용하고 있습니다. – Sam

답변

1

어떤 위 달성하기 위해 3.1 버전에서 지원 이상 혼란 스럽다입니다.

첫 번째 해결책은 훨씬 더 복잡하지만 코드의 다른 부분에서 설명하는 내용이 this 링크에 설명되어있는 경우 멋진 접근 방법입니다. JsonFilter 주석에서 설정 한 특정 mixin (귀하의 경우 CustomEventMixin)을 적용하는 aspect를 정의하는 것이 발생합니다.

는 두 번째 솔루션은 훨씬 간단하고 자신의 잭슨 객체 매퍼를 사용하여 (대신 문자열이 책임을 위임) 다음 코드처럼 당신이 따라 CustomEventMixin를 정의 할 필요가 두 경우 모두

@Controller 
public class EventController { 


    private ObjectMapper objectMapper = new ObjectMapper(); 

    public EventController(ObjectMapper objectMapper) { 
     this.objectMapper = objectMapper; 
     objectMapper.addMixInAnnotations(CustomEvent.class, CustomEventMixin.class); 
    } 

    @RequestMapping("/customEvents") 
    @ResponseBody 
    public String suggest() { 
     return objectMapper.writeValueAsString(getCustomEvents(), new TypeReference<List<CustomEvent>>() {}); 
    } 
} 

을 포함 잭슨은 규칙에

UPDATE :

믹스 인 클래스가 될 것이다 예는 (당신이 ID를 무시하고 싶은 말은)

public interface CustomEventMixin { 

    String name; 

    @JsonIgnore 
    String id; 
} 
+0

CustomEventMixin 클래스 생성 방법 – Sam

+1

' @ JsonIgnore'는 그 일입니다. 서사시! 올바른 자리에서 한 줄의 코드만으로 내 전체 REST 설정을 수정했습니다. –

+0

@ SimonK. 좋은!!! – geoand

2

당신은 아카이브에 @JsonFilter 사용할 수 있습니다.

뽀조 :

@JsonFilter("myFilter") 
public class User { 
    .... 
} 

컨트롤러 :

public String getUser(
      @RequestParam(value="id") String id, 
      @RequestParam(value="requiredFields",required=false) String requiredFields 
     ) throws JsonParseException, JsonMappingException, IOException { 

    //Get User 
    User user = userService.getUser(id); 
    //Start 
    ObjectMapper mapper = new ObjectMapper(); 
    // and then serialize using that filter provider: 
    String json=""; 
    try { 
     if (requiredFields!= null) { 
      String[] fields = requiredFields.split("\\,"); 

      FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", 
      SimpleBeanPropertyFilter.filterOutAllExcept(new HashSet<String>(Arrays 
        .asList(fields)))); 

      json = mapper.filteredWriter(filters).writeValueAsString(user);//Deprecated 
     } else { 
      SimpleFilterProvider fp = new SimpleFilterProvider().setFailOnUnknownId(false); 
      mapper.setFilters(fp); 
      json =mapper.writeValueAsString(user); 
     } 
    } catch (JsonGenerationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (JsonMappingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return json; 
} 

가져 오기 URL : ..... &에서는 requiredfields = ID, 이름,

0

당신은이에 대한 @JsonView 주석을 사용할 수 있습니다 나이 목적. 하지만 불행히도 4.x 이상에서만 작동합니다.

이 내가 아는 가장 깨끗한 방법은 다음과 같습니다

public class View { 
    public interface Summary {} 
    public interface Details extends Summary{} 
} 

Class CustomEvent{ 
    @JsonView(View.Summary.class) 
    long id; 

    @JsonView(View.Summary.class) 
    String eventName; 

    @JsonView(View.Details.class) 
    Account createdBy; 

    @JsonView(View.Details.class) 
    Account modifiedBy; 
} 

@Controller 
public class CustomEventService 
{ 
    @JsonView(View.Summary.class) 
    @RequestMapping("/customEvents") 
    public @ResponseBody List<CustomEvent> getCustomEventSummaries() {} 

    @RequestMapping("/customEvents/{eventId}") 
    public @ResponseBody CustomEvent getCustomEvent(@PathVariable("eventId") Long eventId) {} 
} 

가 @JsonView 주석이없는 기본 필드로도 연재 있음을 알아 두셔야합니다. 그것이 모두에게 주석을 달 필요가있는 이유입니다.

자세한 내용은 읽어 보시기 바랍니다 : https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring

0

내 기존 프로젝트에 대한 비슷한 요구 사항을 가지고 있었다. 하나의 객체가 여러 컨트롤러에 의해 사용됨에 따라 뷰를 도입하는 것이 어려웠습니다. 필터를 구현하는 것은 깨끗한 해결책도 아니 었습니다. 그래서 나는 그 값을 클라이언트에 보내기 전에 Controller의 DTO에서 지우기로 결정했습니다. 그래서 내 자신의 몇 가지 방법을 (더 많은 실행 시간이 걸릴 수 있습니다) 문제를 해결합니다.

public static void includeFields(Object object, String... includeFields) { 
     for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(object)) { 
      if (!Arrays.asList(includeFields).contains(propertyDescriptor.getName())) { 
       clearValues(object, propertyDescriptor); 
      } 
     } 
    } 

    public static void excludeFields(Object object, String... includeFields) { 
     for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(object)) { 
      if (Arrays.asList(includeFields).contains(propertyDescriptor.getName())) { 
       clearValues(object, propertyDescriptor); 
      } 
     } 
    } 

    private static void clearValues(Object object, PropertyDescriptor propertyDescriptor) { 
     try { 
      if(propertyDescriptor.getPropertyType().equals(boolean.class)) { 
       PropertyUtils.setProperty(object, propertyDescriptor.getName(), false); 
      } else { 
       PropertyUtils.setProperty(object, propertyDescriptor.getName(), null); 
      } 
     } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { 
      //TODO 
      e.printStackTrace(); 
     } 
    } 

단점은 항상 페이 존재할 것이다 따라서 값을 가지며 것이다 boolean 필드이다. 최소한 이것은 동적 솔루션을 제공하고 페이로드의 많은 필드를 줄이는 데 도움이되었습니다.

+0

PropertyUtils는 어디에 있습니까? –

+1

클래스는'org.apache.commons.beanutils.PropertyUtils'이며'commons-beanutils.jar'에서 찾을 수 있습니다. – Maz