2017-10-31 2 views
0

다음 예를 가정 해 봅시다. POJO 클래스 :저지. REST 요청에 대한 응답에서 POJO의 필드 중 일부를 숨기는 좋은 방법

@XmlRootElement 
public class User { 
    private String id; 
    private String email; 
    private String password; 
    private String firstName; 
    private String lastName; 

    // getters and setters 
} 

자원 클래스 :

@Path("user") 
public class UserResource { 
    private UserRepository userRepository = new UserRepositoryStub(); 

    @POST 
    @Consumes(MediaType.APPLICATION_JSON) 
    @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) 
    public User createUser(User user) {    
     return userRepository.create(user); 
    } 

    @GET 
    @Path("{objectId}") 
    @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) 
    public Response getManagedObject(@PathParam("objectId") String objectId) { 
     if (objectId == null) { 
      return Response.status(Response.Status.BAD_REQUEST).build(); 
     } 
     User user = userRepository.findUser(objectId); 

     if (user == null) { 
      return Response.status(Response.Status.NOT_FOUND).build(); 
     } 

     // Possible, but seems that not nice solution 
     // user.setPassword(null);    

     return Response.ok().entity(user).build(); 
    }   
} 

이 간단한 예에서 나는 GET 요청이 {URL}/사용자/12345비밀번호를 필드를 반환하지 않는 것을 원하는 . 나는 내가 싫어하는 한 가지 해결책에 대해 논평했다.

일반적으로 API 작업을하는 동안 모든 요청에 ​​대해 POJO의 필드를 볼 수 있도록 설정하고 싶습니다. 달성하기위한 우아한 방법이 있습니까?

답변

1

일반적인 관행 사이에 서비스 계층을하는 것입니다. 그런 다음 외부 세계에 대한 io 객체 인 dto 객체가 리소스/엔티티/저장소/객체로 변환됩니다. 당신은 변환/매퍼/두 가지 유형의 개체 사이에 뭐든간에 제공해야하며 dto 자원 방향으로 갈 때 암호를 설정하지 마십시오. 나머지 인터페이스의 ID에 대해서도 동일한 작업이 일반적으로 수행됩니다. 다른 사용자가 리소스를 업데이트하고 다른 객체를 업데이트하기 위해 입력 객체에 ID를 제공하지 않기를 바랍니다. 이것은 일이 일반적으로 여분의 코드를 의미하는 경우에도 일반적으로 이루어지며, 이는 대개 사소한 것입니다. Dozer 프레임 워크 또는 비슷한 것을 사용하여 구성을 사용하여 단순화 할 수 있습니다.

디자인 관점에서 볼 때 자원/지속성 계층은 단지 원자 연산 만 포함해야합니다. 단일 리소스에 대해 여러 리소스를 수행해야하는 경우 어떻게됩니까? 이를 리소스 클래스의 단일 메서드에 넣어야합니다. 이 방법을 사용하면 나머지/io 논리를 서비스 계층에 있어야하는 것과 혼합 할 수 있습니다. 고립 된 단위 테스트를 작성하는 것이 더 쉽고 실수하기 쉽습니다

+0

감사합니다. 나는 개념을 일반적으로 이해한다. 그것은 아마도 일반적인 접근법 일 것입니다. 어쩌면 당신은 github 또는 다른 곳에서 유사한 오픈 구현 중 일부를 알고있을 것입니다. 코드를 읽는 것이 매우 유용 할 것입니다. – Syb3rian

+1

이것은 내가 디자인 한 예제처럼 보입니다. https://mydevgeek.com/spring-boot-rest-web-service-part-2-crud-operations-service-layers-assemblers-utility-classes/ – MarianP

2

사용자가 JSON 응답에 표시하려는 필드를 보유하고있는 TO 또는 DTO와 같은 TransferObject를 만듭니다. 필드에서 @JsonIgnore를 사용할 수 있으며 JSON 구문 분석기는 해당 필드를 구문 분석하지 않으므로 응답에 포함되지 않습니다.

1

POST 메서드 (마샬링 해제)에 암호 ( )를 포함하고 GET 메서드 (마샬링)를 포함하지 않고 JAXB를 사용한다고 가정하면 XmlAdapter을 쓸 수 있습니다.

해당 프라이머는 매핑 가능 클래스와 매핑 할 수없는 클래스를 변환하는 것이지만 여기에서 트릭을 수행 할 수 있습니다.

public class PasswordAdapter extends XmlAdapter<String, String> { 

    @Override 
    public String unmarshal(String v) throws Exception { 
     return v; 
    } 

    @Override 
    public String marshal(String v) throws Exception { 
     return "***"; 
    } 
} 

그런 다음 암호 속성에 해당 어댑터를 지정합니다

class User { 

    //... 

    @XmlJavaTypeAdapter(PasswordAdapter.class); 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 
관련 문제