踩坑:springboot+freemarker 第二个参数丢失变为FreeMarker

一个用springboot+freemarker做的页面,发生了一件奇怪的事。

页面出了问题后,自动第二次请求get,第一个参数保留,第二个参数被自动替换为FreeMarker

Controller的写法:

@RequestMapping("content/{order}/{district}")
public String getTravelPage(@PathVariable String order, @PathVariable String district, Map<String, Object> model) throws IOException {
    long orderId = 0;
    try {
        //...
        String picSrc = "";
        model.put("PicSrc", picSrc);
        //...
    } catch (Exception ex) {
        logger.warn("getContent Exception ", order, ex);
    }
    return "content";
}

第一遍请求url: localhost:8080/content/123/456

执行到return "content"这一句自动返回controller函数第一行,开始第二遍请求url: localhost:8080/content/123/FreeMarker

为什么会请求第二遍?

为什么第二个参数看起来是丢失赋了默认值?

看了页面的sourcecode, 原因:

content页面:

<img class="topicBox-img" src=${PicSrc}  />

这是第一个需要的参数,controller里面会对freemarker的所有参数赋值,但是由于程序异常,这里的赋值没有赋,直接跳到catch Exception里面执行。return 的页面里面PicSrc是空值。

页面渲染到src=null报错,提示信息:

FreeMarker template error (DEBUG mode; use RETHROW in production!):

The following has evaluated to null or missing:
==> PicSrc  [in template "content.ftl" at line 12, column 41]

由于src是资源,浏览器要加载和访问资源,于是自动访问路径,但是由于报错的提示信息赋在了src后面,浏览器把第一个单词(空格分隔)认为是src的值,浏览器是层级访问,现在已经加载了第一层,也就是localhost:8080/content/123,img的src变为localhost:8080/content/123/FreeMarker

这时又命中的controller的规则,第二次进入controller, 且从int形的参数变成string,又出现错误,彻底加载不了了,页面变为一段报错信息:

PicSrc [in template "content.ftl" at line 12, column 41] ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>

如果页面加载的第一个参数不是src的值,而是一段text则不会二次访问controller, 直接显示报错页面。

解决方法:

1. src等资源要做空的兼容

src=${PicSrc?default('/image/initial.jpg')}

2. try...catch之后也要对model赋值,保证页面需要的参数不是空的。

3. 即使页面失败,也需有失败的补偿。


你可能感兴趣的:(SpringBoot)