如何在Spring应用程序中更改Hateoas输出格式?

时间:2019-07-31 01:00:56

标签: spring spring-mvc spring-hateoas

我目前正在开发一个Spring应用程序,该应用程序提供了一个REST接口,可以对各种实体执行CRUD操作。这些实体存储在存储库中,因此spring会自动生成REST接口的主要部分。当我对这样的实体类型(例如/devices)执行GET请求时,结果如下:

{  
"_embedded":{  
    "devices":[  
        {  
            "macAddress": "...",
            "ipAddress": "...",
            "name": "Device_1",
            "id":"5c866db2f8ea1203bc3518e8",
            "_links":{  
                "self":{  
                    ...
                },
            "device":{  
                ...
            }
        }, ...
    ]
},
"_links":{  
    ...
},
"page":{  
        "size":20,
        "totalElements":11,
        "totalPages":1,
        "number":0
    }
}

现在,我需要手动实现类似的界面,因为还需要进行其他检查。为此,我已经利用了春季风eo功能。但是,我无法实现与spring自动生成的输出结构相同的输出结构。我的控制器类中的相应代码(用RestController注释)如下:

@GetMapping("/devices")
public Resources<Device> getDevices() {
    List<Device> deviceList = getDeviceListFromRepository();

    Link selfRelLink = ControllerLinkBuilder.linkTo(
            ControllerLinkBuilder.methodOn(RestDeviceController.class)
                    .getDevices())
            .withSelfRel();

    Resources<Device> resources = new Resources<>(deviceList);
    resources.add(selfRelLink);

    return resources;
}

配置(节选)如下:

@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
public class WebServletConfiguration extends WebMvcConfigurerAdapter implements ApplicationContextAware {
...
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer c) {
        c.defaultContentType(MediaTypes.HAL_JSON);
    }
...
}

但是,这是请求的输出:

{  
   "links":[  
      {  
         "rel":"self",
         "href":"..."
      }
   ],
   "content":[  
      {  
         "id":"5c866db2f8ea1203bc3518e8",
         "name":"Device_1",
         "macAddress": "...",
         "ipAddress":"...",
      }
   ]
}

如您所见,不是一个_embedded键,而是一个content键,而links键则缺少前划线。这些是我在此输出中遇到的主要问题,与上述输出相比,更详细的差异对我而言并不那么重要。我想统一我的应用程序生成的输出,但是我无法实现spring自动生成的映射的输出格式。我还尝试将resources对象包装到另一个resource对象(如return new Resource<...>(resources))中,但是效果不佳。

您对我在这里做错什么有任何暗示吗?我对Spring&Co还是陌生的,所以请告诉我您是否需要有关某件事的更多信息。非常感谢您的帮助。预先感谢!

1 个答案:

答案 0 :(得分:1)

最后,我能够找到一个解决方案:由于客户端发送了接受标头application/json,因此生成了问题中所示的奇怪输出格式。添加后

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.ignoreAcceptHeader(true);
    configurer.defaultContentType(MediaTypes.HAL_JSON);
}

扩展到WebServletConfiguration的类WebMvcConfigurerAdapter可以正常工作,并且输出格式现在类似于HAL。一个很简单的解决方法,但是花了我数周的时间才弄清楚。也许这个答案将来会对别人有所帮助。