2013-08-22 2 views
1

Мы работаем над сервисом REST, и мы используем Spring MVC для этого же. Мы сталкиваемся с проблемой URL-адреса для решения проблемы. Это примерно то, что мы пытаемся сделатьДифференцируя URL с параметрами Пути

Предположим, что у нас есть люди с их домашними животными

//Class level request mapping 
@RequestMapping("/persons") 

// Mapping to access a specific person inside one of the methods 
@RequestMapping(value="/{personId}", method= RequestMethod.GET 
//.... getPerson method 


// Mapping to access a specific person's pets inside one of the methods 
@RequestMapping(value="/{personId}/pets", method= RequestMethod.GET 
// getPersonPets method 

Если запрос приходит как «/ человек/P12323233», где P12323233 является человек идентификатор, он решает методом getPerson , Если запрос приходит как «/ persons/P12323233/pets», где P12323233 является идентификатором человека, он разрешает метод getPersonPets.

Так что до сих пор все в порядке. Но Если запрос приходит как «/ people/pets», запрос разрешает метод getPerson. Хотя мы можем обрабатывать это как случай ошибки внутри метода getPerson, мы пытаемся проверить, есть ли способ разрешения этого вызова getPersonPets метод.

мы до сих пор обсуждаем ли подходящее место, чтобы обрабатывать этот случай является getPerson или getPersonPets метод. Этими спорами в стороне, мы хотели бы знать, является ли он даже техническим выполним для достижения разрешения к методу getPersonPets.

Цените любую помощь.

+0

URL, четко отображает первый метод. Поэтому, если '' pets "' является существующим идентификатором человека, он должен вернуть этого человека. Если это не так, он должен вернуть ошибку 404 Not Found. Вызов 'getPersonPets()' не имеет особого смысла, и вы все равно не сможете вернуть что-либо полезное, так как у вас нет идентификатора человека, чтобы найти домашних животных. Я сразу же прекратил бы обсуждение :) –

+0

Имеет смысл, что когда есть URL-адрес/лица/домашние животные, он попытается вызвать первый метод и попытается найти человека с идентификатором «домашние животные». если он не найдет, он даст 404. Второй метод никогда не будет выполнен в этом случае. Thnx для ценного ввода. – user2707141

ответ

1

Это можно решить, добавив несколько сопоставлений для одного и того же метода:

@RequestMapping(value="/{personId}", method= RequestMethod.GET 
//.... getPerson method 

@RequestMapping(value = {"/{personId}/pets", "/pets"}, method= RequestMethod.GET 
// getPersonPets method 

Update: Обратите внимание, что с помощью следующей подписи будет сгенерировано исключение при доступе /Домашние животные как PersonId нет в URL:

public String showPets(@PathVariable("personId") long personId) 

Это было бы самый удобный способ доступа к переменной, но, учитывая, что у нас есть несколько путей, сопоставленных с одним и тем же методом, мы могли бы изменить подпись на следующее, чтобы избежать получения исключения:

public String showPets(@PathVariable Map<String, String> vars) 

И получить переменный путь из карты

+0

Использование multipe mapping позволило решить проблему неправильных методов. Но когда я попытался вызвать/людей/домашних животных, это дало мне весеннее исключение, указав, что переменная пути не указана. – user2707141

+0

Правильно, если вы явно определяете имя переменной пути в аннотации, вы получаете исключение, если оно отсутствует в URL-адресе. Вы можете изменить свой метод подписи на: public String showPets (@PathVariable Map vars) {...} и получить переменную пути с карты –

1

Вы также можете использовать регулярные выражения и отфильтровывать такой запрос, как 404. Например:

// Mapping to access a specific person inside one of the methods 
@RequestMapping(value="/{personId:P[\\d]+}", method= RequestMethod.GET 
//.... getPerson method 


// Mapping to access a specific person's pets inside one of the methods 
@RequestMapping(value="/{personId:P[\\d]+}/pets", method= RequestMethod.GET 
// getPersonPets method 
+0

note: fixed regex \\\ d -> \\ d – ikumen

+0

Я пробовал делать это с помощью регулярного выражения. Когда/people/pets invoked..it не вызывают первый метод, но он дал ошибку, заявив, что HTTP 404 запрошен ресурс не найден. – user2707141

+0

Если вы говорите, что нормально иметь/лиц/домашних животных, то вы правы, эти сопоставления не будут работать. Таким образом/люди/домашнее животное/домашние животные возможны? Регулярное выражение основывается на вашем вопросе и предположении, что идентификатор человека имеет форму P ###### .., которая в этом случае тогда/people/pet не является допустимым отображением и возвращает 404. – ikumen

0

Хотя обычно REST предполагает, что вы ссылаетесь идентификатор когда вы не указываете сегмент ресурса, мне нравится добавлять id, чтобы сделать остальную конечную точку менее неоднозначной.

нужно сделать следующее, если вы имеете право изменить API:

//Class level request mapping 
@RequestMapping("/persons") 

// Mapping to access a specific person inside one of the methods 
@RequestMapping(value="/id/{personId}", method= RequestMethod.GET 
//.... getPerson method 


// Mapping to access a specific person's pets inside one of the methods 
@RequestMapping(value="/id/{personId}/pets", method= RequestMethod.GET 
// getPersonPets method 
Смежные вопросы