2016-08-11 16 views
1

最近、私は新しい仕事(4ヶ月)を開始しましたが、まだ春から学ぶことがたくさんあります。私たちが抱えている問題の1つは、DBからオブジェクトを取得し、JSONを(Repository - > Service - > Controller)にマップすると、多くの不要なデータがもたらされることです - 例えば(小さな例):JSONオブジェクトマッピング - スプリングデータ

我々は部門オブジェクトを持つEmployeeクラスを持っており、それは次のようもたらします:

{ 
    'EmployeeId':1, 
    'Name':'John', 
    'Email':'[email protected]' 
    'Department': { 
      'DepartmentId':1, 
      'name':'Development', 
      'location':'Somewhere', 
    } 
} 

クラスの詳細を:

@Entity 
@Table(name = "Employees") 
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employees e") 
public class Employee implements Serializable { 
private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "EmployeeId") 
    private long EmployeeId; 

    @Column(name = "Email") 
    private String email; 

    @Column(name = "address") 
    private String address; 

    @ManyToOne 
    @JoinColumn(name = "DepartmentId") 
    @JsonBackReference(value = "department_employee") 
    private Departament departament; 

    // Other attributes, setters & getters 

} 

私が最善である「カスタム」マッパーを構築したい場合練習?それとも私は私が私にこのような何かをもたらしJSON作成することができます何かを実装する方法:私はいくつかの研究を行ってきたと私は、次の例を偶然見つけ

{ 
    'EmployeeId':'1', 
    'Name':'John', 
    'Email':'[email protected]' 
} 

Jackson JSON Views

をまた、私はので、私は、コントローラ上で、私が欲しいのデータを含めるか、または特定のために必要なことができ HashMapが含まれている一般的なオブジェクトを使用する方法について考えてきた

Jackson's @JsonView, @JsonFilter and Spring

スクリーン。

私は本当に助けていただきありがとうございます。十分な質問があれば幸いです。

+0

ところで、質問もで投稿されました:https://でcoderanch.com/t/669152/Spring/Spring-Mapping-Objects#3124303 –

+0

部門をシリアル化しない場合は、@ JsonIgnorePropertiesアノテーションを使用できます。 – Azizi

+0

私はその質問で指定しなかった場合、私の謝罪 - いくつかの画面で、私は部門を必要とする、例えば私は従業員を更新する必要がある。しかし、名前、電子メール、および特定のデータだけを表示する必要がある場合、それはより適切な方法です。 @ JsonIgnorePropertiesは、フィールドを完全に無視します。 –

答えて

1

私にとって特にうまく機能するライブラリの1つはModel Mapperです。私が使用する方法は、あなたのDomainオブジェクト(今のように)とDTOを持つことです。だからあなたの場合、従業員とEmployeeDTO。これにより、アプリケーションのレイヤー間の明確な分離が可能になり、model mapperを使用してemployeeとemployeeDtoの間のマッピングが非常に簡単になります。例えば、modelMapper(employee, EmployeeDTO.class)です。単純なケースでは、ドメインクラスとdtoクラスで同じ名前のプロパティに名前を付けるだけです。ライブラリは値のコピーを処理します。より複雑なケースでは、コードをきれいにするいくつかの選択肢があります。

+0

ありがとう@Ulises私はそれを試して、それがどのように動作するかを見ていきます。 –

0

セイたとえば、あなたが(ユーザーが作るコメントをキャプチャ)JPAエンティティのコメントがあり、 シリアライズ(オブジェクトからの変換 - > JSON)をカスタマイズしたい

エンティティに

//Comment Entity Attributes (This is just an example make sure you properly annotate the entity etc...): 
private String id; 
private final String userId; 
private String discussionId; 
private final Date createdTime; 
private final String comment; 
を定義します

シリアライザ

を設定

/*Serializer*/ 
import org.springframework.stereotype.Component; 
import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.JsonSerializer; 
import com.fasterxml.jackson.databind.SerializerProvider; 

@Component 
@Slf4j 
public class CommentSerializer extends JsonSerializer<Comment> { 


    @Override 
    public void serialize(Comment comment, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, 
      JsonProcessingException { 
     jgen.writeStartObject(); 
     jgen.writeStringField("id", comment.getId()); 
     jgen.writeStringField("userId", comment.getUserId()); 
     jgen.writeStringField("firstName", redisRepo.getName(comment.getUserId(), false)); 
     jgen.writeStringField("discussionId", comment.getDiscussionId()); 
     jgen.writeStringField("createdTime", String.valueOf(comment.getCreatedTime().getTime())); 
     jgen.writeStringField("comment", comment.getComment()); 
     jgen.writeEndObject(); 
    } 


} 

カスタム・シリアライザを作成します。

/*Config*/ 
import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean; 
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 
import org.springframework.boot.autoconfigure.web.HttpMessageConverters; 

@Autowired 
private CommentSerializer commentSerializer; 

@Bean 
public HttpMessageConverters httpMessageConverters() { 
    return new HttpMessageConverters(mappingJackson2HttpMessageConverter()); 
} 

    @Bean 
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { 
     MappingJackson2HttpMessageConverter mappingJackson2JsonView = new MappingJackson2HttpMessageConverter(); 
     mappingJackson2JsonView.setObjectMapper(objectMapper()); 
     return mappingJackson2JsonView; 
    } 


    @Bean 
    public ObjectMapper objectMapper() { 



     Map<Class<?>, JsonSerializer<?>> serializerMap = new HashMap<>(); 
     serializerMap.put(Comment.class, commentSerializer); 

     Jackson2ObjectMapperFactoryBean objectMapperFactoryBean = new Jackson2ObjectMapperFactoryBean(); 
     objectMapperFactoryBean.setIndentOutput(true); 

     objectMapperFactoryBean.setSerializersByType(serializerMap); 
     objectMapperFactoryBean.afterPropertiesSet(); 

     ObjectMapper objectMapper = objectMapperFactoryBean.getObject(); 
     objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 
     objectMapper.findAndRegisterModules(); 
     objectMapper.addMixInAnnotations(OAuth2Exception.class, OAuth2ExceptionMixin.class); 

     return objectMapper; 
    } 

関連するURL /エンドポイントが、それは常にロジックがCommentSerializerで定義に従って、シリアライズされます(下図のように)呼ばれるたびに)

@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public Comment findOne(@PathVariable("id") String id) 
     .... 
    return comment; 
} 
関連する問題