Freemarker - 撰写语言切换 url

Freemarker - compose language switch url

我正在使用带 Spring 的 freemarker 模板引擎,我想在呈现页面时在 link 元素的 href 属性中添加或替换 lang=xxx 参数。

我找到的最接近的解决方案如下:

<a href="${springMacroRequestContext.getRequestUri()}?lang=en'/>English</a>

但是当我有 URL 参数和片段时这还不够,因为我会想念它们。例如 http://localhost/sports/search?query=Volleyball&lang=cs#some-fragment 结果为 http://localhost/sports/search?lang=en

如何在 freemarker 中添加或更改 lang 参数来编写 URL 并且不遗漏请求的 URL 的任何部分?

我更喜欢在 Java 中这样做,这个简单的实现不考虑散列 (#) 或给定参数在 url..

public static String addParamToUrl(String url, String paramName, String paramValue){
    StringBuffer buffer = new StringBuffer(url);
    //adding separator
    if(url.indexOf('?') == -1){
        buffer.append('?');
    }else if(!url.endsWith("?") && !url.endsWith("&")){
        buffer.append('&');
    }        

    buffer.append(paramName);
    if(paramValue != null){
        buffer.append("=");
        buffer.append(URLEncoder.encode(paramValue, "UTF-8"));
    }
    return buffer.toString();
}

把这个方法放在一个可以被Freemarker引擎静态访问的Class(即:Utils.java)然后:

<#assign url = Utils.addParamToUrl(springMacroRequestContext.getRequestUri(), "lang", "en") />

<a href="${url}">English</a>

要公开您的 Utils class 您必须自定义 FreemarkerManager

public class MyFreemarkerManager extends FreemarkerManager {

    public MyFreemarkerManager(){
        super();
    }

    @Override
    protected void populateContext(ScopesHashModel model, ValueStack stack, Object action, HttpServletRequest request, HttpServletResponse response) {
        super.populateContext(model, stack, action, request, response);

        try {

            BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_24).build();
            TemplateHashModel staticModels = beansWrapper.getStaticModels();

            TemplateHashModel utils = (TemplateHashModel)staticModels.get("com.package.Utils");
            model.put("Utils", utils);  

        } catch (TemplateModelException e) {
            //...
        }       

    }
}

最后您必须告诉 Spring 您正在使用 MyFreemarkerManager 作为 Freemarker 的管理器。