本文介绍了可选择在 Spring Data Rest 中禁用 HATEOAS 格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个现有的应用程序,它有两个端点/people 和/pants.调用 GET/people 返回:

[{"name":"约翰",年龄":37,裤子":[{"颜色":"绿色","品牌":"李维斯",尺寸":中等"},{"颜色":"靛蓝","品牌":"jncos","size":"中等大腿"}]},{"name":"六月",年龄":23,裤子":[{"颜色":"粉红色","品牌":"差距",尺寸":小"}]}]

如果我要使用 Spring Data Rest 并调用 GET/person 我会收到如下信息:

{_链接":{下一个":{"href":"http://myapp.com/people?page=1&size=20"},自己":{"href":"http://myapp.com/people{&page,size,sort}",模板化":真},搜索":{"href":"http://myapp.com/people/search"}},_嵌入":{人们":[{"name":"约翰",年龄":37,_链接":{自己":{"href":"http://myapp.com/people/john"},裤子":{"href":"http://myapp.com/people/john/pants"}}},{"name":"六月",年龄":23,_链接":{自己":{"href":"http://myapp.com/people/june"},裤子":{"href":"http://myapp.com/people/june/pants"}}}]}}

假设我有一堆我不想更改的现有客户端 - 有没有办法在某些情况下禁用响应的超媒体部分(例如 Accept="application/json")但启用为其他人(Accept="hal+json")?

谢谢!

更新

好的 - 所以这让我很懊恼,我想做的事情不受支持.我理解为什么 SDR 强烈倾向于超媒体......但我不相信提供基于标题禁用"超媒体的能力,因此提供更多选项是一件坏事.

除此之外,我有点不确定如何通过我自己的控制器实际实现这一点.如果我创建一个控制器并尝试使用 `produces = "application/json" 覆盖 /people RequestMapping,我可以使用 Accept="application/json" 取回原始"json,但是如果我通过 Accept="application/hal+json" 我得到一个带有找不到可接受的表示"的 406.看起来 SDR 资源映射没有映射到内容类型......有什么建议吗?

解决方案

简短的回答是,没有 hatoas 就不能使用 spring-data-rest.如果您想在没有 hatoas 的情况下构建您的 Web 服务,您必须编写自己的控制器(它仍然可以使用 spring-data 存储库).

这篇SO帖子中引用Oliver Gierke:

实际上我的重点是:服务器只是在做体面的 REST.如果破坏了客户端,需要修复的是客户端(调整).所以超媒体方面是 Spring 的基础数据 REST,我们不会退出.那可能不是满足你的具体情况,但应该回答这个问题至少 :).– 奥利弗吉尔克

So let's say I have an existing application that has two endpoints /people and /pants. Calling GET /people returns:

[
    {
        "name":"john",
        "age":37,
        "pants":[
            {
                "color":"green",
                "brand":"levis",
                "size":"medium"
            },
            {
                "color":"indigo",
                "brand":"jncos",
                "size":"medium-with-huge-legs"
            }
        ]
    },
    {
        "name":"june",
        "age":23,
        "pants":[
            {
                "color":"pink",
                "brand":"gap",
                "size":"small"
            }
        ]
    }
]

If i were to use Spring Data Rest and call GET /person i'd receive something like:

{
    "_links":{
        "next":{
            "href":"http://myapp.com/people?page=1&size=20"
        },
        "self":{
            "href":"http://myapp.com/people{&page,size,sort}",
            "templated":true
        },
        "search":{
            "href":"http://myapp.com/people/search"
        }
    },
    "_embedded":{
        "people":[
            {
                "name":"john",
                "age":37,
                "_links":{
                    "self":{
                        "href":"http://myapp.com/people/john"
                    },
                    "pants":{
                        "href":"http://myapp.com/people/john/pants"
                    }
                }
            },
            {
                "name":"june",
                "age":23,
                "_links":{
                    "self":{
                        "href":"http://myapp.com/people/june"
                    },
                    "pants":{
                        "href":"http://myapp.com/people/june/pants"
                    }
                }
            }
        ]
    }
}

Let's say I have a bunch of existing clients that I don't want to have to change - is there any way to disable the hypermedia portions of the response in some cases (say Accept="application/json") but enable it them for others (Accept="hal+json")?

Thanks!

Updated

Okay - so it appears that much to my chagrin, what I'm looking to do is not supported. I understadn why SDR is are strongly leaning toward Hypermedia... but I don't buy that providing the capability to "disable" hypermedia based on a header thus providing more options is a bad thing.

That aside, I'm a bit unsure of how to actually achieve this via my own Controllers. If I create a Controller and attempt to override the /people RequestMapping with `produces = "application/json" I am able to get the "raw" json back with Accept="application/json" but if i pass Accept="application/hal+json" I get a 406 with "Could not find acceptable representation". It looks like the SDR resource mappings aren't mapped with a content type ... any suggestions?

解决方案

The short answer is, you can't use spring-data-rest without hateoas. If you want to build your web service without hateoas, you'll have to write your own controllers (which can still use spring-data repositories).

Quoting Oliver Gierke in this SO post:

这篇关于可选择在 Spring Data Rest 中禁用 HATEOAS 格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 09:21