【问题标题】:Spring Web Flow: add view state information to URLSpring Web Flow:将视图状态信息添加到 URL
【发布时间】:2020-06-27 21:54:23
【问题描述】:

我正在使用 spring web flow 2.5.1.RELEASE。

我需要在 URL 中显示有关当前视图状态的信息(我需要它来使用谷歌分析跟踪客户旅程)。

假设我有一个具有两个视图状态(命名为一和二)的流程(命名为流程)。

spring web flow生成的url格式为

PROTOCOL://DOMAIN/CONTEXT/SERVLET/FLOW?execution=e?s?

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

我需要网址

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

https://example.com/project/spring/flow?execution=e1s2&viewState=one

当流程处于视图状态 one 并且我需要它时

https://example.com/project/spring/flow/两个?execution=e1s2

https://example.com/project/spring/flow?execution=e1s2&viewState=two

当流处于视图状态两个时。

任何帮助将不胜感激。

问候

【问题讨论】:

    标签: spring url web customization flow


    【解决方案1】:

    经过一些研究和反复试验,我设法找到了一个解决方案,它有点复杂但是......希望有人觉得它有用......

    1 .- 扩展DefaultFlowUrlHandler,重写getFlowId方法处理自定义URL并进行配置

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

    2 .- 扩展 DefaultFlowUrlHandler,覆盖 getFlowExecutionKey(从 cookie 中提取 executionKey)和 createFlowExecutionUrl(设置请求属性 executionKey 并返回自定义 URL)方法并进行配置

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

    3 .- 创建一个过滤器,设置一个 CustomResponseWrapper,该过滤器从请求中获取“executionKey”属性值并使用该值设置一个 cookie。

    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);
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 2011-04-02
      • 1970-01-01
      相关资源
      最近更新 更多