Как по умолчанию выполнить последнюю версию конечной точки в Spring Boot REST? - PullRequest
0 голосов
/ 10 февраля 2020

Я занимаюсь разработкой Spring Boot v2.2.2.RELEASE и версиями API, используя Custom Header. По умолчанию я хочу, чтобы выполнялась последняя версия конечной точки.

Здесь ниже приведен код X-API-VERSION=2. Перед выполнением конечной точки мне нужно проверить отображение, а затем установить последнюю версию для настраиваемого заголовка и затем выполнить его.

@GetMapping(value = "/student/header", headers = {"X-API-VERSION=1"})
public StudentV1 headerV1() {
    return serviceImpl.headerV1();
}

@GetMapping(value = "/student/header", headers = {"X-API-VERSION=2"})
public StudentV1 headerV2() {
    return serviceImpl.headerV2();
}

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Если я правильно понял ваш вопрос, вы хотите, чтобы запрос, отправленный без заголовка X-API-VERSION, автоматически перенаправлялся на headerV2() метод

Это можно сделать:

Концептуально вы ' Вам понадобится веб-фильтр, который будет запущен до сервлета Spring MVC Dispatch, и вам нужно будет проверить, содержит ли запрос заголовок и не добавляет ли он заголовок версии, которая, по вашему мнению, должна быть самой последней ( из конфигурации или еще чего-то).

Одно предостережение здесь заключается в том, что HttpServletRequest не позволяет добавлять заголовки, поэтому вам нужно будет создать HttpServletRequestWrapper и реализовать там логи c добавления заголовков.

Вот пример (я заимствовал реализацию из этого вопроса ):

// The web filter 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;

@Component
@Order(1)
public class LatestVersionFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        if(req.getHeader("X-API-VERSION")== null) {
            HeaderMapRequestWrapper wrappedRequest = new HeaderMapRequestWrapper(req);
            wrappedRequest.addHeader("X-API-VERSION", resolveLastVersion());
            filterChain.doFilter(wrappedRequest, servletResponse);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    private String resolveLastVersion() {
        // read from configuration or something
        return "2";
    }
}

Обратите внимание, что запрос обернут, чтобы добавить заголовок, как я объяснил:

class HeaderMapRequestWrapper extends HttpServletRequestWrapper {
        /**
         * construct a wrapper for this request
         *
         * @param request
         */
        public HeaderMapRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        private Map<String, String> headerMap = new HashMap<String, String>();

        /**
         * add a header with given name and value
         *
         * @param name
         * @param value
         */
        public void addHeader(String name, String value) {
            headerMap.put(name, value);
        }

        @Override
        public String getHeader(String name) {
            String headerValue = super.getHeader(name);
            if (headerMap.containsKey(name)) {
                headerValue = headerMap.get(name);
            }
            return headerValue;
        }

        /**
         * get the Header names
         */
        @Override
        public Enumeration<String> getHeaderNames() {
            List<String> names = Collections.list(super.getHeaderNames());
            for (String name : headerMap.keySet()) {
                names.add(name);
            }
            return Collections.enumeration(names);
        }

        @Override
        public Enumeration<String> getHeaders(String name) {
            List<String> values = Collections.list(super.getHeaders(name));
            if (headerMap.containsKey(name)) {
                values.add(headerMap.get(name));
            }
            return Collections.enumeration(values);
        }

    }

С этой реализацией (убедитесь, что вы кладете сервлет в пакет рядом с контроллером или что-то еще, чтобы пружинная загрузка была распознана выделите его как компонент) вы увидите:

  1. GET с заголовком X-API-VERSION=1 будет перенаправлен на headerV1()
  2. GET с заголовком X-API-VERSION=2 будет перенаправлен на headerV2()
  3. GET без заголовка X-API-VERSION будет перенаправлен на headerV2()
0 голосов
/ 10 февраля 2020

Вы можете добавить метод по умолчанию без заголовка, например:

@GetMapping(value = "/student/header")
public StudentV1 headerDefault() {
    return headerV2();
}

Или просто удалить headers = {"X-API-VERSION=2"} из метода, который должен быть текущим.

...