Spring mvc HTTP-прокси

Я хотел бы написать класс spring MVC Controller, который просто принимает любой HTTP-запрос на вход, добавляет к нему базовые заголовки аутентификации и перенаправляет этот запрос на другой сервер. Я пытаюсь что-то вроде этого без успеха.

    @Controller
    @RequestMapping("/proxyws")
    public class ProxyController {

    @RequestMapping("/**")
    @ResponseBody
    public String mirrorRest( @RequestBody String body, HttpMethod method, HttpServletRequest request, HttpServletResponse response) throws URISyntaxException
    {

        String server = "localhost";
        int port = 8080;
        URI uri = new URI("http", null, server, port, request.getRequestURI(), request.getQueryString(), null);
        RestTemplate restTemplate=new RestTemplate();
        HttpEntity entity = new HttpEntity<String>(body);
        String plainCreds = "APP_CLIENT:APP_PASSWORD"; 
        byte[] plainCredsBytes = plainCreds.getBytes();
        byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
        String base64Creds = new String(base64CredsBytes);
        entity.getHeaders().add("Authorization", "Basic " + base64Creds);

        ResponseEntity<String> responseEntity = restTemplate.exchange(uri, method, entity, String.class);

        return responseEntity.getBody();
    }

Для метода GET на входе я получаю следующее исключение: org.springframework.http.converter.HttpMessageNotReadableException: Отсутствует обязательное содержимое тела запроса:

org.springframework.web.method.HandlerMethod$HandlerMethodParameter@8051792a
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleEmptyBody(RequestResponseBodyMethodProcessor.java:189)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:170)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:105)

Для запроса POST у меня возникают другие проблемы с заголовками базовой аутентификации:

java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableMap.put(Collections.java:1342)
at org.springframework.http.HttpHeaders.add(HttpHeaders.java:831)

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


person C.Giraud    schedule 18.09.2015    source источник
comment
Хотя я уверен, что вы можете заставить это работать с некоторым взломом (вероятно, для начала придется разделить методы GET и POST), и хотя я люблю Spring MVC, представленный вами вариант использования (просто добавление Basic Auth к запросу) очень не подходит для фреймворка MVC. Вы можете выполнить эту задачу проще и эффективнее, используя Nginx. Ознакомьтесь с этим.   -  person geoand    schedule 18.09.2015


Ответы (1)


Вы не можете изменить заголовки объекта HttpEntity после его создания. Вам нужно передать свои заголовки через другой конструктор HttpEntity, например.

public HttpEntity(T body, MultiValueMap<String, String> headers) {
    this.body = body;
    HttpHeaders tempHeaders = new HttpHeaders();
    if (headers != null) {
        tempHeaders.putAll(headers);
    }
    this.headers = HttpHeaders.readOnlyHttpHeaders(tempHeaders);
}

Обратите внимание на инициализацию this.headers: здесь создается копия только для чтения.

person bcody    schedule 07.04.2016