Spring Data Rest - 在 Json 中禁用自我链接(HAL)

Posted

技术标签:

【中文标题】Spring Data Rest - 在 Json 中禁用自我链接(HAL)【英文标题】:Spring Data Rest -Disable self links(HAL) in Json 【发布时间】:2015-05-30 05:02:30 【问题描述】:

我是 spring-data-rest 的新手。在我的应用程序中,当我进行休息调用时,我得到了包含自链接和外键表链接的 json。但我想要json而不是链接。我使用 telosys 工具生成器生成了我的代码。当我对数据库中的“商品”表进行 REST 调用时,这是我的 JSON。:


"id"  : 1,
 "rate": 300,
 "type": "item",
 "shortDescription": "test",
 "longDescription": "test test",

 "_links": 
 "self": 
 "href": "http://localhost:8080/sportsrest/merchandises/1"
 ,
 "listOfMerchandiseAttribute": 
 "href": "http://localhost:8080/sportsrest/merchandises/1/listOfMerchandiseAttribute"
     ,
   
 

但不是获取“listOfMerchandiseAttribute”的链接,我想获取 listOfMerchandiseAttribute 的 JSON。 listOfMerchandiseAttribute 是我在数据库中的另一个表

那就是我想要这样的 json:

  
  "id": 1,
 "rate": 300,
 "type": "item",
 "shortDescription": "test",
 "longDescription": "test test",

 "_links": 
 "self": 
 "href": "http://localhost:8080/sportsrest/merchandises/1"
 ,
 "listOfMerchandiseAttribute":  
         "id": 1,
         "attributeName": "testname",
         "attributeValue": 50     
     ,
   
 

当我在谷歌上搜索时,我得到了一些结果并据此更改了 ApplicationConfig.java 文件,但我仍然得到链接而不是 JSON。这是我的 ApplicationConfig 文件。

ApplicationConfig.java

 /*
 * Created on 19 Mar 2015 ( Time 14:41:07 )
 * Generated by Telosys Tools Generator ( version 2.1.0 )
 */

package co.vitti.sports;

import org.springframework.context.MessageSource;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.http.MediaType;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import co.vitti.sports.validator.BinaryValidator;
import co.vitti.sports.validator.CustomerPackageBalValidator;
import co.vitti.sports.validator.MerchandiseItemValidator;
import co.vitti.sports.validator.CustomerPackageValidator;
import co.vitti.sports.validator.InvoiceValidator;
import co.vitti.sports.validator.UserRoleValidator;
import co.vitti.sports.validator.SportValidator;
import co.vitti.sports.validator.MerchandiseTypeValidator;
import co.vitti.sports.validator.BookingValidator;
import co.vitti.sports.validator.TenantValidator;
import co.vitti.sports.validator.PaymentModeValidator;
import co.vitti.sports.validator.CourtValidator;
import co.vitti.sports.validator.MerchandisePackageValidator;
import co.vitti.sports.validator.CartValidator;
import co.vitti.sports.validator.MigrationValidator;
import co.vitti.sports.validator.TenantSportValidator;
import co.vitti.sports.repository.converter.TenantSportKeyConverter;
import co.vitti.sports.validator.TenantPaymentmodeValidator;
import co.vitti.sports.repository.converter.TenantPaymentmodeKeyConverter;
import co.vitti.sports.validator.MerchandiseAttributeValidator;
import co.vitti.sports.repository.converter.MerchandiseAttributeKeyConverter;
import co.vitti.sports.validator.CartItemValidator;
import co.vitti.sports.validator.MerchandiseValidator;
import co.vitti.sports.validator.UserValidator;
import co.vitti.sports.validator.TimeslotValidator;
import co.vitti.sports.validator.RoleValidator;

import org.springframework.core.convert.support.ConfigurableConversionService;

/**
 * Application configuration.
 * ( messages resources, validators)
 * @author Telosys Tools Generator
 *
 */
@Configuration
@ComponentScan(basePackageClasses = ApplicationConfig.class)
@EnableWebMvc
public class ApplicationConfig extends RepositoryRestMvcConfiguration 

    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config)
        config.setDefaultMediaType((MediaType) MediaType.parseMediaTypes("application/x-spring-data-verbose+json"));
    

    @Bean
    public DataSource dataSource()
        EmbeddedDatabaseBuilder  builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.HSQL).build();

    
    /**
     * Message Ressource declaration.
     * @return MessageRessource
     */
    @Bean
    public MessageSource messageSource() 
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasename("i18n/messages");
        source.setUseCodeAsDefaultMessage(true);
        return source;
    

   /**
     * Validator declaration for Binary
     * @return the BinaryValidator
     */
    @Bean
    public BinaryValidator beforeCreateBinaryValidator() 
        return new BinaryValidator();
    
   /**
     * Validator declaration for CustomerPackageBal
     * @return the CustomerPackageBalValidator
     */
    @Bean
    public CustomerPackageBalValidator beforeCreateCustomerPackageBalValidator() 
        return new CustomerPackageBalValidator();
    
   /**
     * Validator declaration for MerchandiseItem
     * @return the MerchandiseItemValidator
     */
    @Bean
    public MerchandiseItemValidator beforeCreateMerchandiseItemValidator() 
        return new MerchandiseItemValidator();
    
   /**
     * Validator declaration for CustomerPackage
     * @return the CustomerPackageValidator
     */
    @Bean
    public CustomerPackageValidator beforeCreateCustomerPackageValidator() 
        return new CustomerPackageValidator();
    
   /**
     * Validator declaration for Invoice
     * @return the InvoiceValidator
     */
    @Bean
    public InvoiceValidator beforeCreateInvoiceValidator() 
        return new InvoiceValidator();
    
   /**
     * Validator declaration for UserRole
     * @return the UserRoleValidator
     */
    @Bean
    public UserRoleValidator beforeCreateUserRoleValidator() 
        return new UserRoleValidator();
    
   /**
     * Validator declaration for Sport
     * @return the SportValidator
     */
    @Bean
    public SportValidator beforeCreateSportValidator() 
        return new SportValidator();
    
   /**
     * Validator declaration for MerchandiseType
     * @return the MerchandiseTypeValidator
     */
    @Bean
    public MerchandiseTypeValidator beforeCreateMerchandiseTypeValidator() 
        return new MerchandiseTypeValidator();
    
   /**
     * Validator declaration for Booking
     * @return the BookingValidator
     */
    @Bean
    public BookingValidator beforeCreateBookingValidator() 
        return new BookingValidator();
    
   /**
     * Validator declaration for Tenant
     * @return the TenantValidator
     */
    @Bean
    public TenantValidator beforeCreateTenantValidator() 
        return new TenantValidator();
    
   /**
     * Validator declaration for PaymentMode
     * @return the PaymentModeValidator
     */
    @Bean
    public PaymentModeValidator beforeCreatePaymentModeValidator() 
        return new PaymentModeValidator();
    
   /**
     * Validator declaration for Court
     * @return the CourtValidator
     */
    @Bean
    public CourtValidator beforeCreateCourtValidator() 
        return new CourtValidator();
    
   /**
     * Validator declaration for MerchandisePackage
     * @return the MerchandisePackageValidator
     */
    @Bean
    public MerchandisePackageValidator beforeCreateMerchandisePackageValidator() 
        return new MerchandisePackageValidator();
    
   /**
     * Validator declaration for Cart
     * @return the CartValidator
     */
    @Bean
    public CartValidator beforeCreateCartValidator() 
        return new CartValidator();
    
   /**
     * Validator declaration for Migration
     * @return the MigrationValidator
     */
    @Bean
    public MigrationValidator beforeCreateMigrationValidator() 
        return new MigrationValidator();
    
   /**
     * Validator declaration for TenantSport
     * @return the TenantSportValidator
     */
    @Bean
    public TenantSportValidator beforeCreateTenantSportValidator() 
        return new TenantSportValidator();
    
   /**
     * Validator declaration for TenantPaymentmode
     * @return the TenantPaymentmodeValidator
     */
    @Bean
    public TenantPaymentmodeValidator beforeCreateTenantPaymentmodeValidator() 
        return new TenantPaymentmodeValidator();
    
   /**
     * Validator declaration for MerchandiseAttribute
     * @return the MerchandiseAttributeValidator
     */
    @Bean
    public MerchandiseAttributeValidator beforeCreateMerchandiseAttributeValidator() 
        return new MerchandiseAttributeValidator();
    
   /**
     * Validator declaration for CartItem
     * @return the CartItemValidator
     */
    @Bean
    public CartItemValidator beforeCreateCartItemValidator() 
        return new CartItemValidator();
    
   /**
     * Validator declaration for Merchandise
     * @return the MerchandiseValidator
     */
    @Bean
    public MerchandiseValidator beforeCreateMerchandiseValidator() 
        return new MerchandiseValidator();
    
   /**
     * Validator declaration for User
     * @return the UserValidator
     */
    @Bean
    public UserValidator beforeCreateUserValidator() 
        return new UserValidator();
    
   /**
     * Validator declaration for Timeslot
     * @return the TimeslotValidator
     */
    @Bean
    public TimeslotValidator beforeCreateTimeslotValidator() 
        return new TimeslotValidator();
    
   /**
     * Validator declaration for Role
     * @return the RoleValidator
     */
    @Bean
    public RoleValidator beforeCreateRoleValidator() 
        return new RoleValidator();
    

    /**
     * Add all converters for composite keys
     */
    @Override
    protected void configureConversionService(ConfigurableConversionService conversionService) 
        super.configureConversionService(conversionService);
        conversionService.addConverter(this.tenantsportKeyConverter());
        conversionService.addConverter(this.tenantpaymentmodeKeyConverter());
        conversionService.addConverter(this.merchandiseattributeKeyConverter());
    

    /**
     * Converter for the composite key in the TenantSport entity
     * @return the converter
     */
    @Bean
    public TenantSportKeyConverter tenantsportKeyConverter() 
        return new TenantSportKeyConverter();
    
    /**
     * Converter for the composite key in the TenantPaymentmode entity
     * @return the converter
     */
    @Bean
    public TenantPaymentmodeKeyConverter tenantpaymentmodeKeyConverter() 
        return new TenantPaymentmodeKeyConverter();
    
    /**
     * Converter for the composite key in the MerchandiseAttribute entity
     * @return the converter
     */
    @Bean
    public MerchandiseAttributeKeyConverter merchandiseattributeKeyConverter() 
        return new MerchandiseAttributeKeyConverter();
    

 // equivalents for <mvc:resources/> tags
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
    registry.addResourceHandler("/app/**").addResourceLocations("/app/")
    .setCachePeriod(31556926);
    

    // equivalent for <mvc:default-servlet-handler/> tag
    @Override
    public void configureDefaultServletHandling(
    DefaultServletHandlerConfigurer configurer) 
    configurer.enable();
    


谁能帮我解决我的问题并在链接上获取 JSON。 提前致谢。

【问题讨论】:

listOfMerchandiseAttribute 是它自己的存储库吗?如果不是,那么你应该得到完整的 json,而不是链接 @NeilMcGuigan 感谢重播。 listOfMerchandise 不是它自己的存储库。当我对商品表进行 REST 调用时,我得到了上述 JSON。商品表中的主键是listOhMerchandiseAttribute中的外键。所以,我得到了 listOfMerchandiseAttribute 表的链接。但我需要获取该表的 JSON 而不是链接。 【参考方案1】:

您应该确保 listOfMerchandiseAttribute 是您的域类的成员。然后默认转换为 JSON 应该有它。 Spring Data REST 将使用您当前的表示形式并添加超媒体。

另见Disable Hypertext Application Language (HAL) in JSON?

【讨论】:

【参考方案2】:

您可以使用Excerpts(特别为这种情况而设计)。因为 Spring 的例子太有说服力了,在这里复制它很愚蠢,所以我只是指出它:https://docs.spring.io/spring-data/rest/docs/3.1.x/reference/html/#projections-excerpts.excerpting-commonly-accessed-data。 但为了记录和您的方便,我将粘贴 spring 示例的主要部分:

@Projection(name = "inlineAddress", types =  Person.class ) 
interface InlineAddress 
  String getFirstName();
  String getLastName();
  Address getAddress(); 

在Projection javadoc 看到types 表示投影类型绑定到的类型摘录可以这样使用:

@RepositoryRestResource(excerptProjection = InlineAddress.class)
interface PersonRepository extends CrudRepository<Person, Long> 

为了得到这个:


  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "address" :  
    "street": "Bag End",
    "state": "The Shire",
    "country": "Middle Earth"
  ,
  "_links": ...

对于你来说,merchandise 相当于 PersonlistOfMerchandiseAttribute 相当于 address

如何摆脱 _links

在Disable Hypertext Application Language (HAL) in JSON? 上查看我的答案。

结语

Spring 正在发展,因此请注意,这至少适用于:

spring-data-rest-webmvc 3.1.3.RELEASE

或者,如果您更喜欢 Spring Boot 版本:

spring-boot-starter-parent 2.1.1.RELEASE

【讨论】:

【参考方案3】:

一种更简洁的方法是将application.properties 中的以下属性设置为false,同时创建Projections

spring.hateoas.use-hal-as-default-json-media-type=false

【讨论】:

以上是关于Spring Data Rest - 在 Json 中禁用自我链接(HAL)的主要内容,如果未能解决你的问题,请参考以下文章

spring-data-rest 集成测试因简单的 json 请求而失败

在 Spring Data rest json Response 中动态过滤实体字段

纯 JSON(非 HAL 格式)的 Spring Data REST

Spring data rest @ManyToOne 字段不在 json 中

从 Spring Data REST 返回 JSON 响应中的 ID

Jason中的Spring Data Rest -Disable自我链接(HAL)