✅P191_商城业务-检索服务-条件删除与URL编码问题

gong_yz大约 3 分钟谷粒商城

实现页面效果

TODO:待贴图


封装原生的查询条件

cfmall-search/com.gyz.cfmall.search.vo.SearchParam添加_queryString

/**
 * 原生的所有查询条件
 */
private String _queryString;

HttpServletRequestgetQueryString()方法可以获取url的请求参数。

/**
 * @author: gongyuzhuo
 * @description:
 */
@Controller
public class SearchController {
    @Autowired
    MallSearchService mallSearchService;

    /**
     * 自动将页面提交过来的所有请求查询参数封装成指定的对象
     *
     * @param param
     * @param model
     * @return
     */
    @GetMapping(value = "/list.html")
    public String listPage(SearchParam param, Model model,HttpServletRequest request) {
        param.set_queryString(request.getQueryString());
        SearchResult result = mallSearchService.search(param);
        model.addAttribute("result", result);
        return "list";
    }
}

封装链接

com.gyz.cfmall.search.service.impl.MallSearchServiceImpl#buildSearchResult

//6、构建面包屑导航
if (param.getAttrs() != null && param.getAttrs().size() > 0) {
    List<SearchResult.NavVo> collect = param.getAttrs().stream().map(attr -> {
        //1、分析每一个attrs传过来的参数值
        SearchResult.NavVo navVo = new SearchResult.NavVo();
        String[] s = attr.split("_");
        navVo.setNavValue(s[1]);
        R r = productFeignService.attrInfo(Long.parseLong(s[0]));
        if (r.getCode() == 0) {
            AttrResponseVo data = r.getData("attr", new TypeReference<AttrResponseVo>() {
            });
            navVo.setNavName(data.getAttrName());
        } else {
            navVo.setNavName(s[0]);
        }
      	//封装链接
        String replace = param.get_queryString().replace("&attrs=" + attr, "");
        navVo.setLink("http://search.cfmall.com/list.html?" + replace);
        return navVo;
    }).collect(Collectors.toList());
    result.setNavs(collect);
}

问题:路径替换失败

原因:浏览器会将中文进行一个编码,而查询出来的属性值是中文

解决:将中文进行编码

添加代码:encode = URLEncoder.encode(attr,"UTF-8");

//6、构建面包屑导航
if (param.getAttrs() != null && param.getAttrs().size() > 0) {
    List<SearchResult.NavVo> collect = param.getAttrs().stream().map(attr -> {
        //1、分析每一个attrs传过来的参数值
        SearchResult.NavVo navVo = new SearchResult.NavVo();
        String[] s = attr.split("_");
        navVo.setNavValue(s[1]);
        
        //封装属性名
        R r = productFeignService.attrInfo(Long.parseLong(s[0]));
        if (r.getCode() == 0) {
            AttrResponseVo data = r.getData("attr", new TypeReference<AttrResponseVo>() {
            });
            navVo.setNavName(data.getAttrName());
        } else {
            navVo.setNavName(s[0]);
        }

        String encode = null;
        try {
            encode = URLEncoder.encode(attr,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String replace = param.get_queryString().replace("&attrs=" + encode, "");
        navVo.setLink("http://search.cfmall.com/list.html?" + replace);
        return navVo;
    }).collect(Collectors.toList());
    result.setNavs(collect);
}

有些符号,浏览器的编码与java编码不一致;

例如:

  • '(' 浏览器不进行编码,java会编码成 %28
  • ')' 浏览器不进行编码,java会编码成 %29
  • 空格 浏览器会编码成 %20,java会编码成 '+'

解决:添加encode.replace("+","%20");

构建面包屑导航完整代码

//6、构建面包屑导航
if (param.getAttrs() != null && param.getAttrs().size() > 0) {
    List<SearchResult.NavVo> collect = param.getAttrs().stream().map(attr -> {
        //1、分析每一个attrs传过来的参数值
        SearchResult.NavVo navVo = new SearchResult.NavVo();
        String[] s = attr.split("_");
        navVo.setNavValue(s[1]);
        //封装属性名
        R r = productFeignService.attrInfo(Long.parseLong(s[0]));
        if (r.getCode() == 0) {
            AttrResponseVo data = r.getData("attr", new TypeReference<AttrResponseVo>() {
            });
            navVo.setNavName(data.getAttrName());
        } else {
            navVo.setNavName(s[0]);
        }
        //2、取消了这个面包屑以后,我们要跳转到哪个地方,将请求的地址url里面的当前置空
        //拿到所有的查询条件,去掉当前
        String encode = null;
        try {
            encode = URLEncoder.encode(attr,"UTF-8");
            //浏览器对空格的编码和Java不一样,差异化处理
            encode = encode.replace("%28","(").replace("%29",")").replace("+","%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String replace = param.get_queryString().replace("&attrs=" + encode, "");
        navVo.setLink("http://search.cfmall.com/list.html?" + replace);
        return navVo;
    }).collect(Collectors.toList());
    result.setNavs(collect);
}

导航栏回显编写

定位元素

修改 list.html

<div class="JD_ipone_one c">
    <!-- 遍历面包屑功能 -->
    <a th:href="${nav.link}" th:each="nav:${result.navs}"><span th:text="${nav.navName+': '}"></span>
        <span th:text="${nav.navValue}"></span> x
    </a>
</div>

修改replaceParamVal函数。默认是对属性进行一个替换,forceAdd是否强制添加的标识。

function replaceParamVal(url, paramName, replaceVal, forceAdd) {
    var oUrl = url.toString();
    var nUrl;
    if (oUrl.indexOf(paramName) != -1) {
        if( forceAdd ) {
            if (oUrl.indexOf("?") != -1) {
                nUrl = oUrl + "&" + paramName + "=" + replaceVal;
            } else {
                nUrl = oUrl + "?" + paramName + "=" + replaceVal;
            }
        } else {
            var re = eval('/(' + paramName + '=)([^&]*)/gi');
            nUrl = oUrl.replace(re, paramName + '=' + replaceVal);
        }
    } else {
        if (oUrl.indexOf("?") != -1) {
            nUrl = oUrl + "&" + paramName + "=" + replaceVal;
        } else {
            nUrl = oUrl + "?" + paramName + "=" + replaceVal;
        }
    }
    return nUrl;
};

TODO