As the title says, I have a resource object Product
extending ResourceSupport
. However, the responses I receive have the property \"_links\" instea
Spring Boot now (version=1.3.3.RELEASE) has a property that controls the output JSON format of the PagedResources
.
Just add the following config to your application.yml
file:
spring.hateoas.use-hal-as-default-json-media-type: false
if you need the output to be like (based on question):
{
"productId" : 1,
"name" : "2",
"links" : [
{
"rel" : "self"
"href" : "http://localhost:8080/products/1"
}
]
}
Edited:
By the way, you only need @EnableSpringDataWebSupport
annotation in this way.
I've recently had the opposite issue, expected the HAL form (i.e. _links
) but always got links
, although using @EnableAutoConfiguration
.
The solution to my issue might help here as well. Due to copying&pasting from an example I found, I had two mediatypes in my RestController's @RequestMapping
annotation
@RequestMapping(path="/example", produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"})
With @EnableAutoConfiguration
Spring HATEOAS registers an ObjectMapper for application/hal+json
only and in my application there was another one responsible for MediaType.APPLICATION_JSON_VALUE
which won the selection and rendered standard JSON.
So my solution to only set produces="application/hal+json"
so that the Spring HATEOAS object mapper is choosen. In your case you should try to keep MediaType.APPLICATION_JSON_VALUE
I have notice the problem appears at least when you trying to return an object extends ResourseSupport vs object containing object extends ResourseSupport. You may return even List or Array of object(s) extends ResourseSupport and have the same effect. See the example :
@RequestMapping(method = GET, value = "/read")
public NfcCommand statusPayOrder() {
return generateNfcCommand();
}
have response:
{
"field": "123",
"_links": {
"self": {
"href": "http://bla_bla_bla_url"
}
}
}
When try to wrap as List:
@RequestMapping(method = GET, value = "/read")
public List<NfcCommand> statusPayOrder() {
return Arrays.asList(generateNfcCommand());
}
getting:
[
{
"field": 123
"links": [
{
"rel": "self",
"href": "http://bla_bla_bla_url"
}
]
}
]
Changing structure of an answer is not the right decision, but we can try to think further this way.
Another option would be to disable the whole hypermedia auto-configuration feature (this is how it's done in one of the spring-boot
+ REST examples here):
@EnableAutoConfiguration(exclude = HypermediaAutoConfiguration.class)
As far as I know, HypermediaAutoConfiguration
doesn't really do much except for configuring HAL, so it should be perfectly fine to disable it.
I am sure you are using Spring data with @RepositoryRestResource annotation
@RepositoryRestResource
public interface XX extends CrudRepository<AA, String>
If you want to remove default HAL behavior you can add following annotaion param
@RepositoryRestResource(exported = false)
public interface XX extends CrudRepository<AA, String>
Above configurition Spring Data REST to only expose rest endpoints for resources in the parent project, without having to explicitly annotate every repository in the dependency project.
As per doc
Hiding certain repositories, query methods, or fields You may not want a certain repository, a query method on a repository, or a field of your entity to be exported at all. Examples include hiding fields like password on a User object or similar sensitive data. To tell the exporter to not export these items, annotate them with @RestResource and set exported = false.
For example, to skip exporting a Repository:
@RepositoryRestResource(exported = false)
interface PersonRepository extends CrudRepository<Person, Long> {}
If you have HAL available it will be selected for you by spring boot (and "_links" is what you get with HAL). You should be able to @EnableHypermediaSupport
manually to override the defaults.