Перенаправление на стороне сервера для вызова REST

Как лучше всего выполнить перенаправление сторона сервера для вызова REST?

Рассмотрим следующий сценарий:

@RestController
@RequestMapping("/first")
public class FirstController {

    @GetMapping
    public String duStuff(){
        //Redirect to SecondController's doStuff()
    }

}

@RestController
@RequestMapping("/second")
public class SecondController {

    @GetMapping
    public String doStuff(){
        //Redirect here from FirstController's do stuff()
    }

}

Я знаю, что в спецификациях HTTP указано, что для перенаправления следует использовать Коды состояния ответа 3XX, но, насколько я понимаю, это делается на стороне клиента (клиент вызывает URI, указанный в заголовке ответа Location).

Единственный способ реализовать это - использовать RestTemplate, который выполняет запрос от конечной точки в FirstController к конечной точке в SecondController. Это работает, но мне любопытно, есть ли лучший способ добиться этого.

@RestController
@RequestMapping("/first")
public class FirstController {

    @Autowired
    private RestTemplate template;

    @GetMapping
    public String duStuff(){
        /** Is there a better way of doing this, considering I don't want 
            to get the client involved in the redirect to `second`? */
        return template.getForEntity("second", String.class).getBody();
    }

}

Примечание: Это нет приложение Spring MVC (поэтому я не могу перенаправить через return new ModelAndView("redirect:/redirectUrl", model) или RedirectView)

Спасибо за вашу помощь!

Если вы автоматически подключаете SecondController, вы можете просто использовать его функции в своем FirstController, как и с любым другим классом java без отдыха.

T A 24.09.2018 14:33

Спасибо за Ваш ответ! Две мои конечные точки находятся в разных JVM, и между микросервисом, предоставляющим FirstController, и микросервисом, предоставляющим SecondController, нет зависимости кода.

user10367961 24.09.2018 14:37

Используя RedirectView? пример

m4gic 24.09.2018 14:41

Это работает для приложений Spring MVC.

user10367961 24.09.2018 15:59

HttpClient.execute для post / put можно использовать, но я лично предпочитаю restTemplate. Его функции обрабатывают ответ лучше и проще без необходимости чтения из буфера чтения, добавления его в строку и последующего сопоставления с правильным bean-компонентом с помощью объектного сопоставителя (как в случае с httpClient)

Nutan 24.09.2018 18:08

Какой fwk вы используете? Если нет, вы можете попробовать взаимодействовать напрямую с самим ответом: public void doGet (запрос HttpServletRequest, ответ HttpServletResponse) выбрасывает IOException {response.sendRedirect ("google.com ");}

Fabien MIFSUD 24.09.2018 18:09

@NathanHughes Я пытаюсь реализовать поведение 307 Temporary Redirect без вовлечения клиента (вместо того, чтобы полагаться на то, что клиент вызывает URI из заголовка ответа Location, я хочу выполнить перенаправление самостоятельно на стороне сервера). Я не ожидаю, что у меня появятся какие-либо побочные эффекты. Спасибо.

user10367961 25.09.2018 04:40

@FabienMIFSUD Спасибо за ваше предложение, но я думаю, что response.sendRedirect("google.com") по-прежнему полагается на клиент, вызывающий "google.com". Согласно документации, response.sendRedirect() sends a temporary redirect response to the client using the specified redirect location URL and clears the buffer. Что касается фреймворка, я использую стек Spring.

user10367961 25.09.2018 04:44

@Nutan Я рассматриваю возможность использования RestTemplate в методе FirstControllerdoStuff и ручного вызова метода SecondControllerdoStuff через вызов REST. Мне было любопытно, есть ли способ лучше достичь этого (что-то, что работало бы без того, чтобы я вручную перенаправлял запрос). Обновим вопрос, чтобы прояснить это. Спасибо.

user10367961 25.09.2018 04:49

@alexrolea, перенаправление с точки зрения http: клиент запрашивает URL-адрес на сервере, этот сервер отправляет ответ клиенту, чтобы сообщить ему, что ресурс доступен по другому URL-адресу, клиент автоматически вызывает новый URL-адрес. Редирект может быть постоянным или нет. Если вам нужен редирект, это хороший способ. Если вы хотите, чтобы ваш сервер вызывал другой URL-адрес на стороне сервера, используйте restTemplate для вызова другого ресурса и отправки его обратно клиенту.

Fabien MIFSUD 25.09.2018 09:36

@FabienMIFSUD спасибо за ответ!

user10367961 25.09.2018 09:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
11
764
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Похоже на недостаток дизайна. Я бы извлек то, что общего между двумя @Controller, в @Service, а затем вызвал бы @Service из @Controller.

Я пытаюсь реализовать поведение 307 Temporary Redirect без вовлечения клиента (вместо того, чтобы полагаться на то, что клиент вызывает URI из заголовка ответа Location, я хочу выполнить перенаправление самостоятельно на стороне сервера). Никаких дополнительных конструктивных ограничений.

user10367961 25.09.2018 04:37

Для справки: Перенаправление на внешний URL-адрес из действия контроллера в Spring MVC

 @RequestMapping(value = "/redirect", method = RequestMethod.GET)
    public void method(HttpServletResponse httpServletResponse) {
        httpServletResponse.setHeader("Location", projectUrl);
        httpServletResponse.setStatus(302);
    }

Я упомянул ссылку

Nutan 24.09.2018 18:36

Спасибо за ваш ответ, но я думаю, что это работает, когда клиент вызывает URI из заголовка Location, что делает само перенаправление реализованным клиентом. Я хочу сделать перенаправление без участия клиента.

user10367961 25.09.2018 04:30
Ответ принят как подходящий

Если кто-то знает, как этого добиться, оставьте, пожалуйста, ответ, и я приму его.

Стандартной поддержки перенаправления на стороне сервера REST нет.

Для приложения Spring MVC вы можете использовать ModelAndView("redirect:/redirectUrl", model) или RedirectView.

Для REST у вас есть два варианта.

  1. Положитесь на коды состояния 3XX и заголовок Location. Это приведет к тому, что клиент REST выполнит перенаправление, вызвав URL-адрес из заголовка Location.
  2. Используйте RestTemplate (или другой HTTP-клиент) на своем сервере и вручную вызовите URL-адрес, на который вы хотите выполнить перенаправление.

Другие вопросы по теме