springmvc整合freemarker以及前端的一些坑
2017-04-02 19:41
344 查看
一、SpringMVC整合freemarker配置
1、引入相关jar包:
2、添加freemarker配置bean和视图解析器
[html] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<propertynamepropertyname="templateLoaderPath" value="/WEB-INF/view/" />
<propertynamepropertyname="defaultEncoding" value="utf-8" />
<propertynamepropertyname="freemarkerSettings">
<props>
<prop key="template_update_delay">10</prop>
<prop key="locale">zh_CN</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="number_format">#.##</prop>
<prop key="classic_compatible">true</prop>
<prop key="template_exception_handler">com.xxx.web.exception.FreeMarkerExceptionHandler</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<propertynamepropertyname="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
<propertynamepropertyname="suffix" value=".ftl" />
<propertynamepropertyname="contentType" value="text/html;charset=utf-8" />
<propertynamepropertyname="exposeRequestAttributes" value="true" />
<propertynamepropertyname="exposeSessionAttributes" value="true" />
<propertynamepropertyname="exposeSpringMacroHelpers" value="true" />
<propertynamepropertyname="requestContextAttribute" value="request" />
</bean>
二、使用freemarker踩的一些坑
1、关于null值:freemarker对于null值得校验很严格,如果出现null值,而在页面中不进行判断,则会发生异常,通常情况下判断方式有两种:
(1)在页面中使用${prop??}进行判断,或使用${prop?""},若为空则显示“”
(2)可使用配置classic_compatible=true,此种方式只能判断一层,如user.prop为null,显示为空,若user为空,则仍会发生异常。目前的这种情况可使用第一种方式,或者手动创建一个空的对象,保证外层对象不为null即可。
2、freemaker遍历List:
<#list userlist as user></#list>
3、freemarker遍历Map:
<#list userMap?keys as userKey>
key:${userKey}
value:${userMap[userKey]}
</#if>
4、在freemarker页面中使用request对象:配置requestContextAttribute=request,即可使用request,如:
5、freemarker自定义拦截异常:
新建类:
8、table的td内容自动换行:<td style="word-break:break-all">
9、p标签内容换行:<p style="word-wrap:break-word"></p>
10、实现格式化显示:定义时间显示格式:<#setting datetime_format="yyyy-MM-dd HH:mm:ss"/>
使用:${serviceInfo.createTime?number_to_datetime}
11、在使用jquery的datatable时,如果页面中存在注释,一定要特别注意,不能直接使用<!-- -->这样的注释,要用<#--<!-- 修改中,审核驳回 可修改 –>-->,否则注释内容无效,会被datable的搜索功能识别到。暂时还不清楚是谁的原因导致的。
三、bootstrap的一些组件使用说明
1、datatable的使用:包括显示中文,搜索,排序,分页等:
[javascript] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
//初始化表格
if (!jQuery().dataTable) {
return;
}
// 设置表格属性
$('#blacklistTable').dataTable({
"aoColumns": [//是否需要排序,null:需要,要求和页面显示列数相同
null,
null,
null,
null,
null,
{
"bSortable": false,//不参与排序
"bSearchable": false,//不参与搜索
}
],
"aLengthMenu": [
[5, 15, 20, -1],
[5, 15, 20, "所有"] // 每页显示记录数,下拉菜单
],
// set the initial value
"iDisplayLength": 5,//每页初始显示记录数
"sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap",
"oLanguage": {
"sProcessing": "处理中...",
"sLengthMenu": "显示 _MENU_ 项结果",
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
},
"aaSorting": [//默认排序,第2列降序,从0开始
[ 2, "desc" ]
]
});
2、popover显示(信息太长,截取显示,鼠标悬停,显示悬浮框):
data-content:为完整数据,使用<p>标签,加上
,保证正常换行,否则不会换行。
四、第三方组件使用说明
1、alert对象框:使用sweetalert,网址:http://www.dglives.com/demo/sweetalert-master/example/
2、json格式化显示:参考1号店开放平台中的js实现
使用<pre>标签,添加brush:js样式即可。主要是json的换行以及着色。可参考网站:http://alexgorbatchev.com/SyntaxHighlighter/
JSON格式化参考doc.js,格式化后,调用SyntaxHighlighter.highlight();进行高亮显示。
3、js复制内容到粘贴板
(1) 方法一:使用zeroclipboard:http://zeroclipboard.org/ 该方法使用js+flash的方式实现,需要浏览器必须安装flash,否则无法使用,且会造成样式紊乱。
(2)方法二:使用clipboard:https://github.com/zenorocha/clipboard.js ,该方式使用js的方式实现,如果浏览器版本过低则不支持。
使用示例如下:
html页面内容:
[html] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
<p class="info" id="copy_text"></p>
<a href="javascript:void(0);" title="" id="a_trigger_copy" class="action-btn" data-clipboard-target="#copy_text" onclick="copyShortLink()">短链接复制</a>
js代码内容:
[javascript] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
clip = new Clipboard("#a_trigger_copy");//要提前创建对象,不能再点击复制时才创建,否则会导致第一次点击无法复制的问题
if(window.clipboardData) {
//兼容IE浏览器
var clipValue = $("#"+valueId).val();
window.clipboardData.setData("Text",clipValue);
$.alertSuccess("短链接复制成功");
} else {
clip.on("success",function(e){
e.clearSelection();
$.alertSuccess("短链接复制成功");
});
//对于一些版本较低的浏览器不支持自动复制,使用手动方式复制
clip.on('error', function(e) {
$.alertError("请使用Ctrl+C手动复制");
});
}
五:其他
1、反爬虫协议:项目跟路径(webapp)下添加robots.txt文件,内容为:
点击打开链接
1、引入相关jar包:
[html] view plain copy![]()
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.19</version> </dependency
2、添加freemarker配置bean和视图解析器
[html] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<propertynamepropertyname="templateLoaderPath" value="/WEB-INF/view/" />
<propertynamepropertyname="defaultEncoding" value="utf-8" />
<propertynamepropertyname="freemarkerSettings">
<props>
<prop key="template_update_delay">10</prop>
<prop key="locale">zh_CN</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="number_format">#.##</prop>
<prop key="classic_compatible">true</prop>
<prop key="template_exception_handler">com.xxx.web.exception.FreeMarkerExceptionHandler</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<propertynamepropertyname="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
<propertynamepropertyname="suffix" value=".ftl" />
<propertynamepropertyname="contentType" value="text/html;charset=utf-8" />
<propertynamepropertyname="exposeRequestAttributes" value="true" />
<propertynamepropertyname="exposeSessionAttributes" value="true" />
<propertynamepropertyname="exposeSpringMacroHelpers" value="true" />
<propertynamepropertyname="requestContextAttribute" value="request" />
</bean>
二、使用freemarker踩的一些坑
1、关于null值:freemarker对于null值得校验很严格,如果出现null值,而在页面中不进行判断,则会发生异常,通常情况下判断方式有两种:
(1)在页面中使用${prop??}进行判断,或使用${prop?""},若为空则显示“”
(2)可使用配置classic_compatible=true,此种方式只能判断一层,如user.prop为null,显示为空,若user为空,则仍会发生异常。目前的这种情况可使用第一种方式,或者手动创建一个空的对象,保证外层对象不为null即可。
2、freemaker遍历List:
<#list userlist as user></#list>
3、freemarker遍历Map:
<#list userMap?keys as userKey>
key:${userKey}
value:${userMap[userKey]}
</#if>
4、在freemarker页面中使用request对象:配置requestContextAttribute=request,即可使用request,如:
<#assign webroot=request.getContextPath()>
5、freemarker自定义拦截异常:
新建类:
FreeMarkerExceptionHandler
[java] view plain copy![]()
public class FreeMarkerExceptionHandlerimplements TemplateExceptionHandler { private static Logger logger = LoggerFactory.getLogger(FreeMarkerExceptionHandler.class); @Override public void handleTemplateException(TemplateException te, Environment env, Writer out) throws TemplateException { logger.warn("freemarker handleTemplateException",te); throw new ViewException("freemarker error",te); } }
配置:template_exception_handler=xxxx.FreeMarkerExceptionHandler
在web.xml中配置:
[html] view plain copy![]()
<error-page> <exception-type>com.xxx.web.exception.ViewException</exception-type> <location>/error</location> </error-page>
6、freemarker定义变量:<#assign name="xxx">,使用:${name}即可
7、freemarker引入其他页面:<#include "xx.ftl">
8、table的td内容自动换行:<td style="word-break:break-all">
9、p标签内容换行:<p style="word-wrap:break-word"></p>
10、实现格式化显示:定义时间显示格式:<#setting datetime_format="yyyy-MM-dd HH:mm:ss"/>
使用:${serviceInfo.createTime?number_to_datetime}
11、在使用jquery的datatable时,如果页面中存在注释,一定要特别注意,不能直接使用<!-- -->这样的注释,要用<#--<!-- 修改中,审核驳回 可修改 –>-->,否则注释内容无效,会被datable的搜索功能识别到。暂时还不清楚是谁的原因导致的。
三、bootstrap的一些组件使用说明
1、datatable的使用:包括显示中文,搜索,排序,分页等:
[javascript] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
//初始化表格
if (!jQuery().dataTable) {
return;
}
// 设置表格属性
$('#blacklistTable').dataTable({
"aoColumns": [//是否需要排序,null:需要,要求和页面显示列数相同
null,
null,
null,
null,
null,
{
"bSortable": false,//不参与排序
"bSearchable": false,//不参与搜索
}
],
"aLengthMenu": [
[5, 15, 20, -1],
[5, 15, 20, "所有"] // 每页显示记录数,下拉菜单
],
// set the initial value
"iDisplayLength": 5,//每页初始显示记录数
"sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
"sPaginationType": "bootstrap",
"oLanguage": {
"sProcessing": "处理中...",
"sLengthMenu": "显示 _MENU_ 项结果",
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
}
},
"aaSorting": [//默认排序,第2列降序,从0开始
[ 2, "desc" ]
]
});
2、popover显示(信息太长,截取显示,鼠标悬停,显示悬浮框):
data-content:为完整数据,使用<p>标签,加上
word-wrap:break-word
,保证正常换行,否则不会换行。
[html] view plain copy![]()
<spanclassspanclass="popovers" data-html="true" data-trigger="hover" data-placement="bottom" data-content="<p style='word-wrap:break-word;'>${desc}</p>"> <#if desc?length gt 10> ${desc?substring(0,10)}...<!-- 字符串截取第二种方式:${desc[0..10]} --> <#else> ${desc} </#if> </span>
3、列表中显示操作下拉菜单:
[html] view plain copy![]()
<div class="btn-group" style="margin-bottom: 1px !important;"> <a class="btn green" href="#" data-toggle="dropdown"> <i class="icon-cogs"></i>操作 <i class="icon-angle-down"></i> </a> <ul class="dropdown-menu pull-right"> <li><a href="javascript:;" onclick="editBusinessType(${apiBusinessType.id})"><iclassiclass="icon-edit"></i>编辑</a></li> <li><a href="javascript:;" onclick="deleteBusinessType(${apiBusinessType.id})"><iclassiclass="icon-remove"></i>删除</a></li> </ul> </div>
4、表格中,实现列中的内容超出宽度,自动隐藏配置:(可配合popver使用)table:style="table-layout: fixed" td :style="text-overflow: ellipsis;white-space: nowrap;overflow: hidden;"
四、第三方组件使用说明
1、alert对象框:使用sweetalert,网址:http://www.dglives.com/demo/sweetalert-master/example/
[javascript] view plain copy![]()
swal({ title: "解除失败", confirmButtonText: "关闭", })
2、json格式化显示:参考1号店开放平台中的js实现
使用<pre>标签,添加brush:js样式即可。主要是json的换行以及着色。可参考网站:http://alexgorbatchev.com/SyntaxHighlighter/
JSON格式化参考doc.js,格式化后,调用SyntaxHighlighter.highlight();进行高亮显示。
3、js复制内容到粘贴板
(1) 方法一:使用zeroclipboard:http://zeroclipboard.org/ 该方法使用js+flash的方式实现,需要浏览器必须安装flash,否则无法使用,且会造成样式紊乱。
(2)方法二:使用clipboard:https://github.com/zenorocha/clipboard.js ,该方式使用js的方式实现,如果浏览器版本过低则不支持。
使用示例如下:
html页面内容:
[html] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
<p class="info" id="copy_text"></p>
<a href="javascript:void(0);" title="" id="a_trigger_copy" class="action-btn" data-clipboard-target="#copy_text" onclick="copyShortLink()">短链接复制</a>
js代码内容:
[javascript] view
plain copy
![](https://code.csdn.net/assets/CODE_ico.png)
clip = new Clipboard("#a_trigger_copy");//要提前创建对象,不能再点击复制时才创建,否则会导致第一次点击无法复制的问题
if(window.clipboardData) {
//兼容IE浏览器
var clipValue = $("#"+valueId).val();
window.clipboardData.setData("Text",clipValue);
$.alertSuccess("短链接复制成功");
} else {
clip.on("success",function(e){
e.clearSelection();
$.alertSuccess("短链接复制成功");
});
//对于一些版本较低的浏览器不支持自动复制,使用手动方式复制
clip.on('error', function(e) {
$.alertError("请使用Ctrl+C手动复制");
});
}
五:其他
1、反爬虫协议:项目跟路径(webapp)下添加robots.txt文件,内容为:
User-agent: * Disallow: /
2、防XSS攻击:
添加过滤器:XssFilter:
[java] view plain copy![]()
public class XssFilter implements Filter { FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response); } }
配置web.xml:
[html] view plain copy![]()
<filter> <filter-name>defendXssFilter</filter-name> <filter-class>com.yz.open.web.filter.XssFilter</filter-class> <init-param> <param-name>excludedPaths</param-name> <param-value> *.js,*.css,/css/*,/image/*,/js/*,/lib/* </param-value> </init-param> </filter> <filter-mapping> <filter-name>defendXssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
六、freemarker的一些其他使用方式 1、在freemarker中使用layout.extends、layout.put等标签,提高页面重用率,该功能为freemarker提供的自定义标签的实现,此时需要引 入第三方jar包来实现。 (1)引入依赖: [html] view plain copy![]()
<dependency> <groupId>kr.pe.kwonnam.freemarker</groupId> <artifactId>freemarker-template-inheritance</artifactId> <version>0.4.RELEASE</version> </dependency> (2)引入配置文件,用于解析extends,block,put标签 [html] view plain copy
![]()
<import resource="classpath:/kr/pe/kwonnam/freemarker/inheritance/freemarker-layout-directives.xml" /> (3)基础页面:default.ftl(构造页面结构,引入公共css,js,header,footer、menu等公共页面) [html] view plain copy
![]()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <@layout.block name="title"> <title>TestTitle</title> </@layout.block> <!-- global style start --> <#include "includes/global_css.ftl"> <!-- global style end --> <!-- custom style start --> <@layout.block name="custom_style"> </@layout.block> <!-- custom style end --> </head> <body> <!-- page content start --> <@layout.block name="page_content"> </@layout.block> <!-- page content end --> <#include "includes/global_js.ftl"/> <@layout.block name="custom_script"> </@layout.block> </body> </html> (4)实际使用页面:index.ftl(公共css,js等信息已在default.ftl中引入,实际页面只需要引入自己特有的css,js即可) [html] view plain copy
![]()
<@layout.extends name="default.ftl"> <@layout.put block="custom_style"> <#-- 页面样式css --> <link rel="stylesheet" href="${webroot}/css/index.min.css"> </@layout.put> <@layout.put block="page_content"> <#-- 页面内容 --> </@layout.put> <@layout.put block="custom_script"> <#-- 页面脚本js --> <script src="${webroot}/js/index.min.js"></script> </@layout.put> </@layout.extends>
点击打开链接
相关文章推荐
- springmvc整合freemarker以及前端的一些坑
- Strut2和FreeMarker整合时的一些问题
- FREEMARKER与SPRINGMVC整合
- SpringMvc多视图整合配置教程(jsp、velocity、freemarker)
- SpringMVC整合Quartz实现定时任务以及Tomcat服务执行初始化定时任务
- 三大框架整合后Struts2返回Json数据会出现的一些错误以及解决办法
- FreeMarker与SpringMVC整合
- 对spring的访问路径以及配置的一些理解(区分spring的IOC与springMVC的IOC)
- SpringMvc整合Freemarker
- SpringMvc多视图整合(jsp、velocity、freemarker)
- SpringMVC与Freemarker整合获取request对象
- freemarker与springmvc整合
- [spring] springmvc 整合freemarker 出现版本错误
- FreeMarker与SpringMVC整合
- SpringMvc的视图解析器与核心控制器配置以及使用Freemarker模板的配置
- FreeMarker与SpringMVC整合
- php以及前端的一些小小的技术要点
- springMVC整合Freemarker例子
- springmvc定制REST风格 以及 与JSR303 Bean校验整合
- springMVC多视图整合配置教程(jsp,velocity,freemarker)