2014-11-12 2 views
1

РЕДАКТИРОВАНИЕ

Я испытал это на двух разных серверах приложений теперь: 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. Я почти уверен, что это вызвано матричной переменной, и, похоже, во время вызова ControllerLinkBuildermethodOn, но я не могу понять, почему.

У кого-нибудь есть предложения по устранению этой проблемы или (в идеале) исправить ее и устранить необходимость в переменной пути {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-адресе (поэтому переменные пути не могут быть просто разделены двумя дефисами).

ответ

0

Это немного позднее обновление, но было завалено работой.

Я решил эту проблему путем расширения LinkBuilderSupport для моего собственного класса LinkBuilder:

public class RootContextLinkBuilder extends LinkBuilderSupport<RootContextLinkBuilder> { 
    ... 
} 

Проблемы с первоначальной реализацией был в методе getBuilder(). Номер ControllerLinkBuilderServletUriComponentsBuilder.fromServletMapping(request);, который я изменил до ServletUriComponentsBuilder.fromContextPath(request);. Теперь это генерирует правильный href и вызывается так же, как и ControllerLinkBuilder.

Для моего дополнительного вопроса мы застряли с матричными переменными, и поэтому не решили это.

 Смежные вопросы

  • Нет связанных вопросов^_^