当前位置: 首页 > 知识库问答 >
问题:

在Spring Boot中为自定义控制器方法启用HAL序列化

马天逸
2023-03-14
{
  "amount": -4.81,
  "date": "2014-06-17T21:18:00.000+0000",
  "description": "Pizza",
  "_links": {
    "self": {
      "href": "http://localhost:8080/transactions/5"
    },
    "category": {
      "href": "http://localhost:8080/transactions/5/category"
    },
    "account": {
      "href": "http://localhost:8080/transactions/5/account"
    }
  }
}

但现在的目标是只检索该URL下的最新事务,因为我不想序列化整个数据库表。所以我写了一个控制器:

@Controller
public class TransactionController {
    private final TransactionRepository transactionRepository;

    @Autowired
    public TransactionController(TransactionRepository transactionRepository) {
        this.transactionRepository = transactionRepository;
    }

    // return the 5 latest transactions
    @RequestMapping(value = "/transactions", method = RequestMethod.GET)
    public @ResponseBody List<Transaction> getLastTransactions() {
        return  transactionRepository.findAll(new PageRequest(0, 5, new Sort(new Sort.Order(Sort.Direction.DESC, "date")))).getContent();
    }
}

当我现在尝试访问http://localhost:8080/transactions时,有一个

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

因为用户和帐户之间的循环引用。当我通过向用户中的帐户列表添加@JSONBackReference注释来解决这个问题时,我可以检索事务列表,但只能使用以下“经典”格式:

{
  "id": 5,
  "amount": -4.5,
  "date": "2014-06-17T21:18:00.000+0000",
  "description": "Pizza",
  "account": {
    "id": 2,
    "name": "Account Tilman",
    "owner": {
      "id": 1,
      "name": "Tilman"
    },
    "categories": [
      {
        "id": 1,
        "name": "Groceries"
      },
      {
        "id": 2,
        "name": "Restaurant"
      }
    ],
    "users": [
      {
        "id": 1,
        "name": "Tilman"
      }
    ]
  },
  "category": {
    "id": 2,
    "name": "Restaurant"
  }
}
@EnableHypermediaSupport(type = HypermediaType.HAL)
{
    "amount": -4.81,
    "date": "2014-06-17T21:18:00.000+0000",
    "description": "Pizza"
}

共有1个答案

孔权
2023-03-14

这里有很多方面:

>

  • 我怀疑/transactions处的集合资源是否真的像您所描述的那样返回单个事务。为项资源返回这些表示形式。

    如果TransactionRepository已经是PageableAndSortingRepository,则可以通过展开API根目录中为名为Transactions的链接公开的URI模板来调整集合资源。默认情况下,这是pagesizesort参数。这意味着客户端已经可以请求您想公开的内容。

    您需要注意以下几个帮助器:

    • PersistentEntityResourceAssembler-它通常被注入到控制器方法中。它以Spring Data REST方式呈现单个实体,这意味着指向托管类型的关联将呈现为链接等
    • PagedResourcesAssembler-通常注入到控制器实例中。负责准备页中包含的项,可选择使用专用的ResourceAssembler.

    Spring Data REST对页面的主要作用如下:

    PersistentEntityResourceAssembler entityAssembler = …;
    Resources<?> … = pagedResourcesAssembler.toResources(page, entityAssembler);
    

  •  类似资料:
    • 我正在使用谷歌Gson将Java对象序列化到JSON中。现在,我正在使用方法为一些类添加自定义序列化。通过使用这个,我需要将我想要序列化的所有类导入到我的项目中。 由于我正在处理一个项目,其中一个对象可以附加自定义类,所以我正在寻找一个解决方案,在这个解决方案中,我创建一个特定的方法(例如,),并告诉Gson在以默认模式序列化之前搜索该方法。 当Gson发现这个方法存在时,它会使用它,否则它会继续

    • 控制器定义 ThinkCMF5的控制器完全按 TP5的控制器用法来,但 CMF 封装了几个重要控制器基类,为了更方便开发者,我们建议如果没有特殊需求,自己创建的控制器请最好继承一个基类控制器; 用于 WEB 项目的基类控制器有四个,分别是:BaseController,HomeBaseController,UserBaseController,AdminBaseController 继承关系 th

    • 控制器定义 ThinkCMF6.0的控制器完全按 TP6.0的控制器用法来,但 CMF 封装了几个重要控制器基类,为了更方便开发者,我们建议如果没有特殊需求,自己创建的控制器请最好继承一个基类控制器; 用于 WEB 项目的基类控制器有四个,分别是:BaseController,HomeBaseController,UserBaseController,AdminBaseController, Re

    • 控制器定义 控制器文件通常放在application/module/controller下面,类名和文件名保持大小写一致,并采用驼峰命名(首字母大写)。 一个典型的控制器类定义如下: <?php namespace app\index\controller; use think\Controller; class Index extends Controller { public fu

    • 我有一个关于JCache/Ehcache-XML配置的问题。 我将JSR 107缓存注释CDI参考实现与Ehcache一起使用。 我想用@CacheResult注释特定方法,以便这些方法的结果将缓存在为该特定方法生成的缓存中。在我们的例子中,这些方法的返回值是可选的,您可能知道,可选实例不可序列化,因此默认情况下不能缓存。默认使用的序列化拷贝器和PlainJavaSerializer在这方面失败。