use*_*465 0 javascript hateoas angularjs spring-data-rest spring-hateoas
tl; dr
我的代码从Restful GET获取了一系列javascript / json对象。如何编写代码以循环并从HATEOAS“ _link”属性检索描述(或任何值)以进行显示?
语境
我继承了一个基于Spring的小型项目,该项目跟踪服务器,软件安装等,供我们团队内部使用。它使用Angular前端和Spring / java / mysql后端实现宁静的后端。
我正在将手动编码的SQL转换为JPA和“ Spring Starter Data Rest”
目前的API
当前的手工编码SQL连接表以提供“显示友好的结果”。
Product
---------
Product ID
Product Name
Category ID
Category
---------
Category ID
Category Name
Run Code Online (Sandbox Code Playgroud)
“检索产品” sql将产品和类别连接在一起,以给出“显示友好名称”。Rest API检索带有此“类别名称”的“产品对象”。
Spring Data Rest域对象
产品
@Entity
@Table(name="products")
public class Products
{
private static final long serialVersionUID = 5697367593400296932L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long id;
public String product_name;
@ManyToOne(optional = false,cascade= CascadeType.MERGE)
@JoinColumn(name = "category_id")
private ProductCategory productCategory;
public Products(){}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Products(String product_name) {
this.product_name = product_name;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public ProductCategory getProductCategory()
{
return productCategory;
}
public void setProductCategory(ProductCategory pProductCategory)
{
productCategory = pProductCategory;
}
}
Run Code Online (Sandbox Code Playgroud)
产品分类
@Entity
@Table(name="productcat")
public class ProductCategory implements Serializable{
private static final long serialVersionUID = 890485159724195243L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long id;
public String category;
@OneToMany(mappedBy = "productCategory", cascade = CascadeType.ALL)
@JsonBackReference
Set<Products> products;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public Set<Products> getProducts() {
return products;
}
}
Run Code Online (Sandbox Code Playgroud)
问题
我删除了联接,并为产品和类别添加了Spring存储库。现在,“获取产品”静态API将返回以下列表:
{
"product_name" : "ForceFive 1.0",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/rest/products/8"
},
"products" : {
"href" : "http://localhost:8080/api/rest/products/8"
},
"productCategory" : {
"href" : "http://localhost:8080/api/rest/products/8/productCategory"
}
}
Run Code Online (Sandbox Code Playgroud)
题
如何显示“ productCategory”链接的类别名称?
"productCategory" : {
"href" : "http://localhost:8080/api/rest/products/8/productCategory"
}
Run Code Online (Sandbox Code Playgroud)
我最初以为我可以检索类别,然后将“类别url”映射到“描述”。但是网址不同:
“产品类别”网址看起来像这样: http:// localhost:8080 / api / rest / productcat / 1
而产品具有以下内容:“ productCategory”:{“ href”:“ http:// localhost:8080 / api / rest / products / 8 / productCategory ”}
问题澄清
因此,如果javascript控制器http获得了以下产品:
requests.get(productsUrl, $scope).success(function(data, status){
$scope.models = data._embedded.products;
});
Run Code Online (Sandbox Code Playgroud)
那又如何呢?这些步骤是吗?
javascript控制器遍历每个data._embedded.products。每个产品的代码
http获取产品类别网址
productCategory“:{” href“:” http:// localhost:8080 / api / rest / products / 8 / productCategory “}
http获取类别
“产品分类”: {
"href": "http://localhost:8080/api/rest/productcat/4"
Run Code Online (Sandbox Code Playgroud)
},
-将描述存储在页面上的某个地方以供重用(即,将其添加到javascript对象中)
如果是这些步骤:
即使我添加了一个调用以获取/缓存所有产品类别,仍然可以获得额外的50 http
奖励:
尝试#01:添加投影
我添加了这个投影:
public interface ProductRepository extends PagingAndSortingRepository<Products, Long>
{
@Projection(name = "dummyNameForProjection", types = { Products.class })
interface VirtualProjection
{
String getProduct_name() ;
//Get Product Category
@Value("#{target.productCategory.category}")
String getCategoryName();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,此url不返回类别名称:
http://localhost:8080/api/rest/products/4?projection=dummyNameForProjection
Run Code Online (Sandbox Code Playgroud)
返回的json
{
"product_name": "Force Five",
"_links": {
"self": {
"href": "http://localhost:8080/api/rest/products/4"
},
"products": {
"href": "http://localhost:8080/api/rest/products/4"
},
"productCategory": {
"href": "http://localhost:8080/api/rest/products/4/productCategory"
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我为这些设置了调试功能
logging.level.org.springframework.data=DEBUG
logging.level.org.springframework.data.rest=DEBUG
logging.level.org.hibernate=DEBUG
Run Code Online (Sandbox Code Playgroud)
日志/控制台未提及任何投影。
尝试#02:修复 D下的D'oh 投影文件。我将投影卡在存储库上而不是实体上。查看一些示例代码显示了此问题。投影就是门票!
小智 5
@Projection(name = "dummyNameForProjection", types = { Product.class })
public interface VirtualProjection {
// this will get the attribute name from the product entity
String getProductName();
//this will get the name of the category entity related to the product
@Value("#{target.category.name}")
String getCategoryName();
Run Code Online (Sandbox Code Playgroud)
}
只需在您的请求中包括投影名称即可:/ products?projection = dummyNameForProjection