MongoDB의 경우 필드가 일시적이지만 RestController의 경우 필드가 아님을 지정합니다.
MongoDB로 지속되는 REST 인터페이스를 제공하기 위해 스프링 부트를 사용하고 있습니다.을 공급하고 . 에는 저표 ' 준을 ' 속성 ' 사여 ' 용하 ' 종는 ' 전고 ' 력을 있습 ' 등이 포함됩니다.spring-boot-starter-data-mongodb
그리고.spring-boot-starter-web
.
일부 을 달지 않는 .@Transient
MongoDB가 해당 정보를 보유하지 않도록 합니다.하지만, 제가 원하는 이 정보는 휴식 서비스로 보내집니다.안타깝게도 MongoDB와 나머지 컨트롤러는 모두 해당 주석을 공유하는 것 같습니다.따라서 프런트 엔드가 JSON 개체를 수신할 때 해당 필드는 인스턴스화되지 않지만 선언됩니다.주석을 제거하면 JSON 개체에서 필드를 통과할 수 있습니다.
MongoDB와 REST에 대해 임시적인 것을 별도로 구성하려면 어떻게 해야 합니까?
여기 내 수업이 있습니다.
package com.clashalytics.domain.building;
import com.clashalytics.domain.building.constants.BuildingConstants;
import com.clashalytics.domain.building.constants.BuildingType;
import com.google.common.base.Objects;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import java.util.*;
public class Building {
@Id
private int id;
private BuildingType buildingType;
private int level;
private Location location;
// TODO http://stackoverflow.com/questions/30970717/specify-field-is-transient-for-mongodb-but-not-for-restcontroller
@Transient
private int hp;
@Transient
private BuildingDefense defenses;
private static Map<Building,Building> buildings = new HashMap<>();
public Building(){}
public Building(BuildingType buildingType, int level){
this.buildingType = buildingType;
this.level = level;
if(BuildingConstants.hpMap.containsKey(buildingType))
this.hp = BuildingConstants.hpMap.get(buildingType).get(level - 1);
this.defenses = BuildingDefense.get(buildingType, level);
}
public static Building get(BuildingType townHall, int level) {
Building newCandidate = new Building(townHall,level);
if (buildings.containsKey(newCandidate)){
return buildings.get(newCandidate);
}
buildings.put(newCandidate,newCandidate);
return newCandidate;
}
public int getId() {
return id;
}
public String getName(){
return buildingType.getName();
}
public BuildingType getBuildingType() {
return buildingType;
}
public int getHp() {
return hp;
}
public int getLevel() {
return level;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public BuildingDefense getDefenses() {
return defenses;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Building building = (Building) o;
return Objects.equal(id, building.id) &&
Objects.equal(hp, building.hp) &&
Objects.equal(level, building.level) &&
Objects.equal(buildingType, building.buildingType) &&
Objects.equal(defenses, building.defenses) &&
Objects.equal(location, building.location);
}
@Override
public int hashCode() {
return Objects.hashCode(id, buildingType, hp, level, defenses, location);
}
}
그대로.hp
그리고.defenses
0
그리고.null
각각 다음과 같다.만약 내가 그것을 제거한다면.@Transient
꼬리표를 붙입니다.
을 한.org.springframework.data.annotation.Transient
예상대로 작동해야 합니다.잭슨은 스프링 데이터에 대해 아무것도 모르고 주석을 무시합니다.
작동하는 샘플 코드:
interface PersonRepository extends CrudRepository<Person, String> {}
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
class Person {
@Id
private String id;
private String name;
@Transient
private Integer age;
// setters & getters & toString()
}
@RestController
@RequestMapping("/person")
class PersonController {
private static final Logger LOG = LoggerFactory.getLogger(PersonController.class);
private final PersonRepository personRepository;
@Autowired
PersonController(PersonRepository personRepository) {
this.personRepository = personRepository;
}
@RequestMapping(method = RequestMethod.POST)
public void post(@RequestBody Person person) {
// logging to show that json deserialization works
LOG.info("Saving person: {}", person);
personRepository.save(person);
}
@RequestMapping(method = RequestMethod.GET)
public Iterable<Person> list() {
Iterable<Person> list = personRepository.findAll();
// setting age to show that json serialization works
list.forEach(foobar -> foobar.setAge(18));
return list;
}
}
POST 실행 중 http://localhost:8080/person
:
{
"name":"John Doe",
"age": 40
}
- 출력 그력 출
Saving person: Person{age=40, id='null', name='John Doe'}
- 의
person
컬션렉:{ "_id" : ObjectId("55886dae5ca42c52f22a9af3"), "_class" : "demo.Person", "name" : "John Doe" }
.
GET 실행 중 http://localhost:8080/person
:
- 결과:
[{"id":"55886dae5ca42c52f22a9af3","name":"John Doe","age":18}]
@JsonSerialize를 사용하여 해결했습니다.또한 선택적으로 @JsonDeserialize를 선택할 수도 있습니다. 이 경우에도 마찬가지로 비활성화됩니다.
@Entity
public class Article {
@Column(name = "title")
private String title;
@Transient
@JsonSerialize
@JsonDeserialize
private Boolean testing;
}
// No annotations needed here
public Boolean getTesting() {
return testing;
}
public void setTesting(Boolean testing) {
this.testing = testing;
}
당신의 문제는 몽고와 잭슨 둘 다 예상대로 행동하고 있다는 것입니다.Mongo는 데이터를 유지하지 않으며 Jackson은 속성이 일시적으로 표시되므로 속성을 무시합니다.인 필드를 하도록 '를 부린 에 잭이슨꼼 '일를시수 '적고할있 ', 그다 더나방다 '로 을 달음으로써 이 을 할 수 .@JsonProperty
여기 제 샘플 콩이 있습니다.
@Entity
public class User {
@Id
private Integer id;
@Column
private String username;
@JsonIgnore
@Transient
private String password;
@JsonProperty("password")
public String getPassword() {
return // your logic here;
}
}
이것은 적절한 해결책이라기보다는 해결책에 가깝기 때문에 당신에게 부작용이 생길지 모르겠습니다.
carlos-combiescas, 당신은 그것에 어떤 버전을 사용하고 있습니까?버전 문제일 수 있습니다.이 일시적인 주석은 몽고브에 지속되지 않는 것만을 의미하기 때문입니다.버전을 변경해 보십시오.Maciejone(1.2.4 릴리스)과 유사할 수 있습니다.
버전 중 하나에서 스프링 데이터 프로젝트에 대한 json 구문 분석에 문제가 있습니다.http://www.widecodes.com/CyVjgkqPXX/fields-with-jsonproperty-are-ignored-on-deserialization-in-spring-boot-spring-data-rest.html
당신은 당신의 것을 노출하지 않기 때문에.MongoRepositories
Spring Data REST를 사용하여 안정적인 엔드포인트를 구축하는 것이 보다 합리적입니다.Resources/endpoint
응답이 도메인 모델과 분리되어 있기 때문에 나머지 클라이언트/서버에 영향을 미치지 않고 도메인 모델이 진화할 수 있습니다.리소스의 경우 Spring HATOAS가 제공하는 기능을 활용하는 것을 고려할 수 있습니다.
주석 org.bson.codecs.pojo.notations를 사용할 수 있습니다.MongoDB가 유지되지 않도록 필드에서 @transient 대신 BsonIgnore.
@BsonIgnore
private BuildingDefense defenses;
그것은 또한 게터에도 효과가 있습니다.
사용자 정의를 구현하여 이 문제를 해결했습니다.JacksonAnnotationIntrospector
:
@Bean
@Primary
ObjectMapper objectMapper() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
AnnotationIntrospector annotationIntrospector = new JacksonAnnotationIntrospector() {
@Override
protected boolean _isIgnorable(Annotated a) {
boolean ignorable = super._isIgnorable(a);
if (ignorable) {
Transient aTransient = a.getAnnotation(Transient.class);
JsonIgnore jsonIgnore = a.getAnnotation(JsonIgnore.class);
return aTransient == null || jsonIgnore != null && jsonIgnore.value();
}
return false;
}
};
builder.annotationIntrospector(annotationIntrospector);
return builder.build();
}
이 코드는 보이지 않게 합니다.org.springframework.data.annotation.Transient
에 대한 주석.Jackson
하지만 효과가 있습니다.mongodb
.
언급URL : https://stackoverflow.com/questions/30970717/specify-field-is-transient-for-mongodb-but-not-for-restcontroller
'itsource' 카테고리의 다른 글
WebMvcTest에서 Eureka 및 Spring Cloud Config를 비활성화하는 방법은 무엇입니까? (0) | 2023.07.16 |
---|---|
DateTimeOffset.이제 T-SQL에서 (0) | 2023.07.16 |
git pull --기본값과 git pull --off-only의 차이 (0) | 2023.07.06 |
LIKE '%에 대한 PL/SQL 성능 조정...와일드카드 쿼리 (0) | 2023.07.06 |
git 하위 모듈 업데이트가 'detected submodule: detected in repository: (0) | 2023.07.06 |