Я пытаюсь написать контроллер с Spring MVC 3.2, который потребляет/производит как JSON, так и HTML. У меня есть два метода обработчика, которые создают разные типы контента:
@Controller
public class FooController {
@RequestMapping(value="/foo", produces="text/html")
public String fooHTML() {
// ...
}
@RequestMapping(value="/foo", produces="application/json")
public String fooJSON() {
// ...
}
}
Это прекрасно работает, если заголовок Accept
от клиента содержит либо text/html
, либо application/json
,
...но потом появился Internet Explorer. Как отмечено здесь, заголовок Accept
в IE различается, но никогда не содержит text/html
и всегда имеет */*
в конце. Когда Spring получает запрос от IE, он не видит типов контента, непосредственно равных типам, созданным моим контроллером, но, привязываясь к подстановочному знаку */*
, он (правильно) решает, что будут применяться оба сопоставления.
Столкнувшись с несколькими совпадающими сопоставлениями обработчиков, Spring (в bean-компоненте RequestMappingHandlerMapping) сортирует сопоставления по тому, что по существу соответствует лексикографическому порядку, выбирает первое и движется дальше. Проблема, с моей точки зрения, в том, что этот процесс отдает приоритет application/json
, а не text/html
. Я бы предпочел вернуть text/html
, если только клиент специально не запрашивает application/json
— таким образом я могу предоставлять HTML для тупых клиентов, таких как IE, и JSON для клиентов, разбирающихся в типах контента, таких как пользователи моего API.
Кто-нибудь знает способ сделать это, который не требует расширения RequestMappingHandlerMapping для другой сортировки обработчиков? У вас есть простые обходные пути?
ПРИМЕЧАНИЕ. Я попытался установить тип контента по умолчанию в ContentNegotiationManager, как описано в блоге Spring. Это не решает мою проблему, потому что этот параметр вступает в силу, только если заголовок Accept не указан.