Spring Web Flow: добавление информации о состоянии просмотра в URL - PullRequest
1 голос
/ 16 марта 2020

Я использую Spring Web Flow 2.5.1.RELEASE.

Мне нужно показать информацию о текущем состоянии просмотра в URL-адресе (она мне нужна для отслеживания поездок клиентов с помощью Google Analytics).

Допустим, у меня есть поток (именованный поток) с двумя состояниями просмотра (именованные одно и два).

Формат URL-адреса, сгенерированного веб-потоком весны:

ПРОТОКОЛ: / / DOMAIN / CONTEXT / SERVLET / FLOW? Выполнение = e? S?

ie) https://example.com/project/spring/flow?execution=e1s2

Мне нужно, чтобы URL был

https://example.com/project/spring/flow/ один ? Исполнение = e1s2

или

https://example.com/project/spring/flow?execution=e1s2 & viewState = один

когда поток находится в состоянии просмотра один , и мне нужно, чтобы он был

https://example.com/project/spring/flow/ два ? выполнение = e1s2

или

https://example.com/project/spring/flow?execution=e1s2 & viewState = два

, когда поток находится в состоянии просмотра два .

Любая помощь будет принята с благодарностью.

С уважением

1 Ответ

0 голосов
/ 01 апреля 2020

После некоторых исследований, проб и ошибок мне удалось найти решение, оно немного сложное, но ... надеюсь, кто-то найдет его полезным ...

1 .- Расширьте DefaultFlowUrlHandler, переопределите метод getFlowId работать с пользовательскими URL-адресами и настраивать их

@Bean
public FlowHandlerMapping flowHandlerMapping() {
    FlowHandlerMapping mapping = new FlowHandlerMapping();
    mapping.setFlowUrlHandler(customFlowUrlHandlerForFlowHandlerMapping());
    ...

2 .- Расширить DefaultFlowUrlHandler, переопределить методы getFlowExecutionKey (для извлечения executeKey из cook ie) и createFlowExecutionUrl (для установки атрибута запроса executeKey и возврата настраиваемого URL-адреса) и сконфигурируйте его

@Bean
public FlowHandlerAdapter flowHandlerAdapter() {
    JsfFlowHandlerAdapter adapter = new JsfFlowHandlerAdapter();
    adapter.setFlowExecutor(this.webFlowConfig.flowExecutor());
    adapter.setFlowUrlHandler(customFlowUrlHandlerForFlowHandlerAdapter());
    return adapter;
}

3 .- Создайте фильтр, который устанавливает CustomResponseWrapper, который принимает значение атрибута executeKey из запроса, и задайте для повара ie это значение.

4 .- Как примечание, этот метод может использоваться, чтобы избавиться от параметра URL выполнения.

5 .- Java код

public class FlowUrlhandlerForFlowHandlerMapping extends DefaultFlowUrlHandler /* CustomDefaultFlowUrlHandler */ {

    private final Logger logger = LoggerFactory.getLogger(FlowUrlhandlerForFlowHandlerMapping.class) ;

    // pathInfo: /landing-planes/oferta
    private String PATH_INFO_PREFIX = "/landing-planes/" ;

    /**
     * Return correct flowId for custom URL
     */
    @Override
    public String getFlowId(HttpServletRequest request) {
        String pathInfo = request.getPathInfo();
        logger.info("getFlowId - pathInfo: " + pathInfo) ;
        if (pathInfo != null) {
            if (pathInfo.startsWith(PATH_INFO_PREFIX)) {
                logger.info("getFlowId - Retornando landing-planes como flowId!!!");
                return "landing-planes" ;
            }
        }
        String flowId = super.getFlowId(request);
        logger.info("getFlowId(" + request + "): " + flowId);
        return flowId ;
    }

}
public class FlowUrlHandlerForFlowHandlerAdapter extends DefaultFlowUrlHandler /* CustomDefaultFlowUrlHandler */ {


    private final Logger logger = LoggerFactory.getLogger(FlowUrlHandlerForFlowHandlerAdapter.class) ;

    // pathInfo: /landing-planes/oferta
    private String PATH_INFO_PREFIX = "/landing-planes/" ;

    private static final String PATH_INFO_FLOW_INIT = "/landing-planes/init";

    /**
     * Extract and return flowExecutionKey from cookie.
     */
    @Override
    public String getFlowExecutionKey(HttpServletRequest request) {
        String flowExecutionKey = super.getFlowExecutionKey(request); 
        logger.info("getFlowExecutionKey - super.getFlowExecutionKey: " + flowExecutionKey);

        String pathInfo = request.getPathInfo();
        logger.info("getFlowExecutionKey - pathInfo: " + pathInfo) ;

        if (!pathInfo.startsWith(PATH_INFO_PREFIX)) {
            return flowExecutionKey ;
        }

        if (pathInfo.equals(PATH_INFO_FLOW_INIT)) {
            return flowExecutionKey ;
        }

        Cookie cookieSwf = null;
        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals("swf")) {
                cookieSwf = cookie ;
            }
        }
        if (cookieSwf != null) {
            String value =  cookieSwf.getValue() ;
            logger.warn("El valor de la cookie es " + value) ;
            if (value == null) {
                logger.warn("El valor de la cookie es null") ;
            } else {
                String fek = value ;
                logger.info("fek: " + fek);
                flowExecutionKey = fek ;
            }
        }
        return flowExecutionKey ;
    }

    /**
     * If custom url, set request attribute 'executionKey' and return new custom url (indicated by application logic in 'view' attribute of the request)
     */
    @Override
    public String createFlowExecutionUrl(String flowId, String flowExecutionKey, HttpServletRequest request) {
        String flowExecutionUrl = super.createFlowExecutionUrl(flowId, flowExecutionKey, request);
        // /suscripciones-ventas/spring/landing-planes/oferta?execution=e2s2
        logger.info("createFlowExecutionUrl(" + flowId + ", " + flowExecutionKey + ", request): " + flowExecutionUrl);

        String pathInfo = request.getPathInfo();
        logger.info("createFlowExecutionUrl - pathInfo: " + pathInfo) ;
        // /suscripciones-ventas/spring/landing-planes/init


        if (pathInfo.startsWith(PATH_INFO_PREFIX)) {
            String vista = (String) request.getAttribute("view") ;
            logger.info("vista: " + vista);
            if (vista == null) {
                vista = pathInfo.replace(PATH_INFO_PREFIX, "") ;
                logger.info("vista tomada del path info: " + vista);
            }
            return procesarUrl(flowExecutionUrl, request, "/suscripciones-ventas/spring/landing-planes/" + vista) ;
        }

        return flowExecutionUrl ;
    }

    private String procesarUrl(String flowExecutionUrl, HttpServletRequest request, String customUrl) {
        String executionKey = extractExecutionKey(flowExecutionUrl) ;
        logger.info("executionKey: " + executionKey);
        if (executionKey != null) {
            request.setAttribute("executionKey", executionKey);
        }
        logger.info("procesarUrl - customUrl: " + customUrl) ;
        return customUrl ;
    }

    private String extractExecutionKey(String string) {
        if (string == null) {
            logger.warn("El valor pasado como parametro es null") ;
        } else {
            int index = string.indexOf("?execution=") ;
            if (index == -1) {
                logger.warn("El valor pasado como parametro no contiene execution '" + string + "'") ; 
            } else {
                String fek = string.substring(index + "?execution=".length()) ;
                logger.info("fek: " + fek);
                return fek ;
            }
        }
        return null ;
    }

}
@Component
public class CustomSpringFilter extends GenericFilterBean {

    private static Logger logger = LoggerFactory.getLogger(CustomSpringFilter.class) ;

    private static String SWF_CUSTOM_URI_PREFIX = "/suscripciones-ventas/spring/landing-planes/" ;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {

        HttpServletRequest httpServletRequest = ((HttpServletRequest)request) ;
        String requestURI = httpServletRequest.getRequestURI() ;

        boolean processRequest = processRequest(requestURI) ;
        if (!processRequest) {
            chain.doFilter(request, response);
            return ;
        }

        logger.info("**************************");
        logger.info("requestURI: " + requestURI);
        if (requestURI.startsWith(SWF_CUSTOM_URI_PREFIX)) {
            HttpServletResponse httpServletResponse = ((HttpServletResponse)response) ;
            procesarRequest(chain, httpServletRequest, httpServletResponse);
            return;
        }

        chain.doFilter(request, response);

    }

    private String[] ignoreExtensionArray = {".js", ".css", ".jpg", ".png"} ;

    private boolean processRequest(String requestURI) {
        for (int i = 0; i < ignoreExtensionArray.length; i++) {
            if (requestURI.endsWith(ignoreExtensionArray[i])) {
                return false ;
            }
        }
        if (requestURI.endsWith("pase/onLogin")) {
            return false ;
        }
        return true ;
    }

    private void procesarRequest(
        FilterChain filterchain, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse
    ) throws IOException, ServletException {
        CustomResponseWrapper responseWrapper = new CustomResponseWrapper(httpServletResponse, httpServletRequest);
        filterchain.doFilter(httpServletRequest, responseWrapper);
    }

}
public class CustomResponseWrapper extends HttpServletResponseWrapper {

    private static Logger logger = LoggerFactory.getLogger(CustomResponseWrapper.class) ;

    private HttpServletRequest httpServletRequest ;

    private boolean checked = false ;

    public CustomResponseWrapper(HttpServletResponse response, HttpServletRequest httpServletRequest) {
        super(response);
        this.httpServletRequest = httpServletRequest ;
    }

    @Override
    public void sendRedirect(String location) throws IOException {
        logger.info("sendRedirect: " + location);
        checkAttributeAndSetCookie();
        super.sendRedirect(location);
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        checkAttributeAndSetCookie();
        return super.getWriter();
    }   

    private void checkAttributeAndSetCookie() {
        if (checked) {
            return ;
        }
        checked = true ;
        String executionKey = (String) httpServletRequest.getAttribute("executionKey");
        logger.info("executionKey: " + executionKey);
        if (executionKey != null) {
            Cookie cookie = new Cookie("swf", executionKey) ;
            super.addCookie(cookie);
        }
    }

}
...