Контроллер REST от Grails отвечает неправильным типом контента - программирование

Контроллер REST от Grails отвечает неправильным типом контента

Я пытаюсь написать контроллер Grails REST, который всегда должен отвечать JSON. Ниже приведен контроллер:

class TimelineController {

    static allowedMethods = [index: "GET"]
    static responseFormats = ['json']

    TimelineService timelineService

    def index(TimeLineCommand command) {
        List<TimelineItem> timeline = timelineService.currentUserTimeline(command)
        respond timeline
    }
}

Я использую метод respond, который является частью поддержки REST от Grails, поэтому согласование контента используется для определения типа ответа на рендеринг. В этом конкретном случае я ожидал бы, что JSON будет выбран, потому что контроллер указывает

    static responseFormats = ['json']

Кроме того, я написал (и зарегистрировал в Spring) следующий рендерер, чтобы настроить формат JSON, который возвращается для List<TimelineItem>

class TimelineRenderer implements ContainerRenderer<List, TimelineItem> {

    @Override
    Class<List> getTargetType() {
        List
    }

    @Override
    Class<TimelineItem> getComponentType() {
        TimelineItem
    }

    @Override
    void render(List timeline, RenderContext context) {

        context.contentType = MimeType.JSON.name
        def builder = new JsonBuilder()

        builder.call(
            [items: timeline.collect { TimelineItem timelineItem ->

                def domainInstance = timelineItem.item

                return [
                        date: timelineItem.date,
                        type: domainInstance.class.simpleName,
                        item: [
                                id   : domainInstance.id,
                                value: domainInstance.toString()
                        ]
                ]
            }]
        )

        builder.writeTo(context.writer)
    }

    @Override
    MimeType[] getMimeTypes() {
        [MimeType.JSON] as MimeType[]
    }
}

Я написал некоторые функциональные тесты и вижу, что хотя мой обработчик вызывается, разрешенный тип контента text/html, поэтому контроллер возвращает 404, потому что он не может найти GSP с ожидаемым именем.

Я сильно подозреваю, что проблема связана с использованием настраиваемого средства визуализации, потому что у меня есть другой почти идентичный контроллер, который не использует собственный рендерер, и он правильно разрешает тип контента.

4b9b3361

Ответ 1

Похоже, вам нужно создать пробел (по крайней мере) index.gsp в разделе

grails-app/views/timeline/

чтобы сделать рендеринг. Я успешно возвращаю тип содержимого как application/json

Такое поведение меня сильно беспокоит, и я все еще смотрю на него. Это стоит вопрос JIRA. Если вам нужно, я могу подтолкнуть свое фиктивное приложение к github.

UPDATE:
Проблема создана в github (со ссылками на пример приложения).
https://github.com/grails/grails-core/issues/716

Ответ 2

  • В Config.groovy необходимо указать grails.mime.types. Подробности можно найти здесь: Grails 2.3.11 Консолидация контента. По крайней мере, вам нужно иметь следующее в Config.groovy:

    grails.mime.types = [
        json: ['application/json', 'text/json']
    ]
    
  • Если вы хотите ответить настроенным JSON, рекомендуется render someMap as JSON.

  • О вашей проблеме 404 вам нужно сделать response.setContentType('application/json') в действии вашего контроллера. Формат ответа по умолчанию Grails - html, так что он будет искать gsp файл для рендеринга, если тип contentType не указан.