Как лучше всего выполнить перенаправление сторона сервера для вызова 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)
Спасибо за вашу помощь!
Спасибо за Ваш ответ! Две мои конечные точки находятся в разных JVM, и между микросервисом, предоставляющим FirstController, и микросервисом, предоставляющим SecondController, нет зависимости кода.
Используя RedirectView? пример
Это работает для приложений Spring MVC.
HttpClient.execute для post / put можно использовать, но я лично предпочитаю restTemplate. Его функции обрабатывают ответ лучше и проще без необходимости чтения из буфера чтения, добавления его в строку и последующего сопоставления с правильным bean-компонентом с помощью объектного сопоставителя (как в случае с httpClient)
Какой fwk вы используете? Если нет, вы можете попробовать взаимодействовать напрямую с самим ответом: public void doGet (запрос HttpServletRequest, ответ HttpServletResponse) выбрасывает IOException {response.sendRedirect ("google.com ");}
@NathanHughes Я пытаюсь реализовать поведение 307 Temporary Redirect без вовлечения клиента (вместо того, чтобы полагаться на то, что клиент вызывает URI из заголовка ответа Location, я хочу выполнить перенаправление самостоятельно на стороне сервера). Я не ожидаю, что у меня появятся какие-либо побочные эффекты. Спасибо.
@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.
@Nutan Я рассматриваю возможность использования RestTemplate в методе FirstControllerdoStuff и ручного вызова метода SecondControllerdoStuff через вызов REST. Мне было любопытно, есть ли способ лучше достичь этого (что-то, что работало бы без того, чтобы я вручную перенаправлял запрос). Обновим вопрос, чтобы прояснить это. Спасибо.
@alexrolea, перенаправление с точки зрения http: клиент запрашивает URL-адрес на сервере, этот сервер отправляет ответ клиенту, чтобы сообщить ему, что ресурс доступен по другому URL-адресу, клиент автоматически вызывает новый URL-адрес. Редирект может быть постоянным или нет. Если вам нужен редирект, это хороший способ. Если вы хотите, чтобы ваш сервер вызывал другой URL-адрес на стороне сервера, используйте restTemplate для вызова другого ресурса и отправки его обратно клиенту.
@FabienMIFSUD спасибо за ответ!




Похоже на недостаток дизайна. Я бы извлек то, что общего между двумя @Controller, в @Service, а затем вызвал бы @Service из @Controller.
Я пытаюсь реализовать поведение 307 Temporary Redirect без вовлечения клиента (вместо того, чтобы полагаться на то, что клиент вызывает URI из заголовка ответа Location, я хочу выполнить перенаправление самостоятельно на стороне сервера). Никаких дополнительных конструктивных ограничений.
Для справки: Перенаправление на внешний URL-адрес из действия контроллера в Spring MVC
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void method(HttpServletResponse httpServletResponse) {
httpServletResponse.setHeader("Location", projectUrl);
httpServletResponse.setStatus(302);
}
Я упомянул ссылку
Спасибо за ваш ответ, но я думаю, что это работает, когда клиент вызывает URI из заголовка Location, что делает само перенаправление реализованным клиентом. Я хочу сделать перенаправление без участия клиента.
Если кто-то знает, как этого добиться, оставьте, пожалуйста, ответ, и я приму его.
Стандартной поддержки перенаправления на стороне сервера REST нет.
Для приложения Spring MVC вы можете использовать ModelAndView("redirect:/redirectUrl", model) или RedirectView.
Для REST у вас есть два варианта.
3XX и заголовок Location. Это приведет к тому, что клиент REST выполнит перенаправление, вызвав URL-адрес из заголовка Location.RestTemplate (или другой HTTP-клиент) на своем сервере и вручную вызовите URL-адрес, на который вы хотите выполнить перенаправление.
Если вы автоматически подключаете
SecondController, вы можете просто использовать его функции в своемFirstController, как и с любым другим классом java без отдыха.