РЕДАКТИРОВАНИЕ
Я испытал это на двух разных серверах приложений теперь: Tomcat 8.0.15 и JBoss 6.2 EAP. Ссылка правильно генерируется на Tomcat, а на JBoss она некорректно генерируется. Кроме того, я создал небольшой образец проекта для демонстрации проблемы:Матричные Переменные продуцирующие неправильно HATEOAS ссылки
https://github.com/Vile2539/hateoas-link-test/tree/master
Оригинал Вопрос
Я недавно был изменить некоторые из моих услуг Spring REST использовать matrix variables вместо переменных пути. Это, однако, привело к некорректным ссылкам HATEOAS, которые генерируются ControllerLinkBuilder.
То, что я в настоящее время:
Метод контроллера
Там в целом @RequestMapping
из /test-items
по этому вопросу. Кроме того, из того, что я понимаю и проверил, требуется @PathVariable
, поскольку одного только шаблона URL недостаточно. Вот почему существует {fullString}
.
@RequestMapping(value = "/{fullString}/test", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8"})
@ResponseBody
public PagedCollectionResource test(@PathVariable String fullString, @MatrixVariable String testVariable, Pageable pageable) {
Link link = linkTo(methodOn(TestControllerImpl.class).test(fullString, testVariable, pageable)).withSelfRel();
Page<TestItem> testItems = testService.getPagedTestItems(testVariable, pageable);
return testService.getPagedCollectionResource(testItems, link);
}
Spring Config
<mvc:annotation-driven enable-matrix-variables="true">
<mvc:path-matching path-helper="pathHelper"/>
<mvc:argument-resolvers>
<bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean id="pathHelper" class="org.springframework.web.util.UrlPathHelper">
<property name="alwaysUseFullPath" value="true"/>
<property name="urlDecode" value="false"/>
<property name="removeSemicolonContent" value="false"/>
</bean>
обслуживания вызовов
http://localhost:8080/testItem/test-items/stringhere;testVariable=036/test
Результат
"links":[{"rel":"self","href":"http://localhost:8080/testItem/test-items/stringhere/test-items/stringhere;testVariable=036/test{?page,size,sort}"}]
Как вы можете видеть, по какой-то причине есть еще /test-items/stringhere
. Я почти уверен, что это вызвано матричной переменной, и, похоже, во время вызова ControllerLinkBuilder
methodOn
, но я не могу понять, почему.
У кого-нибудь есть предложения по устранению этой проблемы или (в идеале) исправить ее и устранить необходимость в переменной пути {fullString}
?
Дополнительный вопрос
Кроме того, причина для использования матричных переменных, чтобы получить вокруг вопроса кодирования URL. Я был ранее отделяя переменные пути с дефисом -
, так что-то вроде:
{variable1}-{variable2}
К сожалению, оба могут содержать специальные символы, такие как /
, -
, &
и т.д.Используя alwaysUseFullPath
и urlDecode
свойства видели выше, я был в состоянии пройти в большинстве специальных символов, закодированных - поэтому вызов выше с косой чертой будет:
/test-items/%2Fab-v%2Fc/test
variable1 = /ab
variable2 = v/c
Это не было, однако, работа для черточек - закодированный дефис будет неперекодированным и приведет к неверному переменному пути:
/test-items/a%2db-vc/test
variable1 = a
variable2 = b-vc
Двойной кодирующей дефис, однако, делает работу - но, очевидно, ужасным хак.
Если у кого-то есть предложения по обойти это при сохранении вызова GET, я был бы очень благодарен. Нельзя делать никаких предположений о порядке или типе символов в URL-адресе (поэтому переменные пути не могут быть просто разделены двумя дефисами).