Spring Data Rest 投影不适用于单个资源
Spring Data Rest projection does not work for single resources
我为一个实体编写了以下投影 class。
@Projection(name = "instituteProjection", types = { Institute.class })
public interface InstituteProjection {
String getOrganizationName();
Address getRegisteredAddress();
}
现在,每当我调用 url http://localhost:8080/institutes/1?projection=instituteProjection
时,我都会尝试应用此投影,其中 return 是一个学院资源。控制器GET方法实现如下:
@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
Institute institute = service.getInstitute(instituteId);
return new ResponseEntity<>(institute, HttpStatus.OK);
}
问题是这不是return学院投影。它 return 是默认存储库 json。
投影只有在我使用 SDR 生成的控制器而不是我已经实现的自定义其余控制器时才有效。
那么如何在自定义控制器中应用投影?
更新 1
研究所class
@Data
@Entity
public class Institute{
private String organizationName;
@OneToOne
private Address registeredAddress;
@OneToOne
private Address mailingAddress;
}
更新 2
地址class
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private long addressID;
@ManyToOne
private Street street;
@ManyToOne
private Country country;
private double latitude;
private double longitude;
@ManyToOne
private City city;
}
非常简单。您可以使用现有的投影,甚至可以删除 @Projection
注释,这不是强制使用自定义控制器的。
所以最小投影是:
public interface InstituteProjection {
String getOrganizationName();
Address getRegisteredAddress();
}
现在,要转换您的学院实体,您需要实施 ProjectionFactory
interface, an existing one is SpelAwareProxyProjectionFactory
。
要使该类型的 bean 可访问,请添加一个小配置:
@Configuration
public class ProjectionFactoryConfig {
@Bean
public ProjectionFactory projectionFactory() {
return new SpelAwareProxyProjectionFactory();
}
}
现在您可以在您的控制器中使用它来将您的 Institute 转换为您的 InstituteProjection:
@Autowired
private ProjectionFactory projectionFactory;
...
@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
final Institute institute = service.getInstitute(instituteId);
final InstituteProjection instituteProjection = projectionFactory.createProjection(InstituteProjection.class, institute);
return new ResponseEntity<>(instituteProjection, HttpStatus.OK);
}
我为一个实体编写了以下投影 class。
@Projection(name = "instituteProjection", types = { Institute.class })
public interface InstituteProjection {
String getOrganizationName();
Address getRegisteredAddress();
}
现在,每当我调用 url http://localhost:8080/institutes/1?projection=instituteProjection
时,我都会尝试应用此投影,其中 return 是一个学院资源。控制器GET方法实现如下:
@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
Institute institute = service.getInstitute(instituteId);
return new ResponseEntity<>(institute, HttpStatus.OK);
}
问题是这不是return学院投影。它 return 是默认存储库 json。
投影只有在我使用 SDR 生成的控制器而不是我已经实现的自定义其余控制器时才有效。
那么如何在自定义控制器中应用投影?
更新 1 研究所class
@Data
@Entity
public class Institute{
private String organizationName;
@OneToOne
private Address registeredAddress;
@OneToOne
private Address mailingAddress;
}
更新 2
地址class
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private long addressID;
@ManyToOne
private Street street;
@ManyToOne
private Country country;
private double latitude;
private double longitude;
@ManyToOne
private City city;
}
非常简单。您可以使用现有的投影,甚至可以删除 @Projection
注释,这不是强制使用自定义控制器的。
所以最小投影是:
public interface InstituteProjection {
String getOrganizationName();
Address getRegisteredAddress();
}
现在,要转换您的学院实体,您需要实施 ProjectionFactory
interface, an existing one is SpelAwareProxyProjectionFactory
。
要使该类型的 bean 可访问,请添加一个小配置:
@Configuration
public class ProjectionFactoryConfig {
@Bean
public ProjectionFactory projectionFactory() {
return new SpelAwareProxyProjectionFactory();
}
}
现在您可以在您的控制器中使用它来将您的 Institute 转换为您的 InstituteProjection:
@Autowired
private ProjectionFactory projectionFactory;
...
@RequestMapping(value = "institutes/{instituteId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getInstitute(@PathVariable Long instituteId) {
final Institute institute = service.getInstitute(instituteId);
final InstituteProjection instituteProjection = projectionFactory.createProjection(InstituteProjection.class, institute);
return new ResponseEntity<>(instituteProjection, HttpStatus.OK);
}