对比的写下struts2与springmvc,这两个web框架
1.在web项目中的web.xml中配置与简单开发
struts2中
<!-- 引入struts核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果你不想自己的struts.xml放在classe目录下可以使用以下方法
方法一:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>filterConfig</param-name>
<!--将文件放在strut2文件夹下-->
<param-value>classpath:struts2/struts.xml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
方法二:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>struts-default.xml,struts-plugin.xml,../config/struts.xml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
方法三:
加载初始struts2文件
使用include包含一个struts.xml文件
<struts>
<include file=”config/struts.xml”></include>
</struts>
ps:个人没有觉得三种方法比默认加载有多大好处,所以常常还是使用默认的
springmvc中
<!-- 注册springmvc框架核心控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--如果你想在其它目录下配置可以直接写目录加配置文件名spring/springmvc.xml
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--注意此处的内容如果写成/*,将会出现controller执行正常,但是无法访问jsp页面-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
2.执行流程与简单的不同开发方式(xml与注解)
xml方式
struts2中
1.用户访问action.服务器根据访问路径名称,找对应的action位置,创建action,执行默认拦截器中定义的18个拦截器,执行action的业务处理方法。
action类,也叫做动作类。一般继承actionsupport类
public class HelloAction extends ActionSupport{
public String execute() throws Exception{
//execute为默认的执行方法
}
}
<package name="XXXX" extends="struts-default">
<action name="hello" class="com.zhenzhigu.action.HelloAction" method="execute">
<result name="success">/success.jsp</result>
</action>
</package>
springmvc中
前端控制器叫处理器映射器去找handler,找到之后前端控制在叫处理器适配器处理handler,处理器适配器处理完成后再返回ModelAndView,前端控制器叫视图解析器解析形成返回的jsp文件,最后前端控制器自己处理将数据填充request域,而后向用户响应结果
这货是第一步上阵的
<!-- 注册控制器(程序员) -->
<bean name="/add.action" class="com.zhenzhigu.j2ee.springmvc.mapping.UserAction"></bean>
<!-- 注册映射器(handler包)(框架) -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!--另一种写法是
<!-- 注册映射器(handler包)(框架) -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/delete.action">userActionID</prop>
<prop key="/update.action">userActionID</prop>
<prop key="/find.action">userActionID</prop>
</props>
</property>
</bean>
-->
这货是第二步执行的
public class testspringmvc implements Controller{
//需要实现controller接口,才能被配置的SimpleControllerHandlerAdapter适配器执行
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
...
//向request域中添加数据
modelAndView.addObject("test",testlist);
//指定视图
modelAndView.setViewName("/WEB-INF/jsp/test.jsp");
return modelAndView;
}
}
ps:如果你不想使用modelAndview这个部分可以实现HttpRequestHandler可以使用request转发到相应的jsp页面文件
注解的方式
struts2中
使用controller注解添加到action上,将需要的bean使用Resource注解或Autowired,那么之后在struts2.xml配置文件中class时无需再写controller类的全路径,将controller的名称写即可(类名默认首字母小写)
@Controller
public class ThisHuo extends ActionSupport{
....
}
struts2.xml文件的配置方式
<action name="findHuo" class="thisHuo" method="execute">
<result name="success">/thishuo.jsp</result>
</action>
springmvc中
常用注解开发,在这里可以使用responsebody返回一个json字符串,使用requestMapping处理指定url访问地址,使用PathVarible形成resultful风格的url地址。。。。。
springmvc.xml中配置
<!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置
mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
实际开发时使用mvc:annotation-driven
-->
<!-- <mvc:annotation-driven></mvc:annotation-driven> -->
java代码
@Controller
@RequestMapping(value="/this")
public class ThisHuo implements Controller{
@RequestMapping(value="/huo")
public String test(Model model) throws Exception{
return "index";
}
}
3.数据的封装
struts2中
.html表单采集数据->提交表单->Action 底层依赖HTTP传递数据,而HTTP协议中没有“类型”的概念。每一项表单输入只可能是一个字符串或一个字符串数组。因此在服务器端Action中必须把String转换为业务需要的特定的数据类型
struts2框架会将表单的参数以同名的方式设置给对应Action属性中,该工作主要是由Parameters拦截器做的。而该拦截器中已经自动的实现了String到基本数据类型之间转换工作。类似于:Beanutils工具
声明:string到基本数据类型的转换是自动的
ps:其中String到Date日期类的转换是有条件(默认输入框输入的格式必须是yyyy-MM-dd,其它格式无法转换)
1.基本数据类型的封装是
form表单的数据名称与action类中的成员变量同名
action类中添加成员变量
pirvate String username;
jsp中
<input name="username"/>
...
2.对象中属性的封装
action类中
private HUO huo;
jsp中
<input name="huo.name"/>
3.集合数据类型封装
action类
private Collection<HUO> huos;
jsp中
<input name="huo[0].name"/>
<input name="huo[0].time"/>
<input name="huo[1].name"/>
<input name="huo[2].time"/>
4.数组类型封装
action类中
添加
private String ans[];
。。。。
jsp中
<input name="ans" value="1"/>
<input name="ans" value="2"/>
5.map类型封装
action类
private UserMap<String> userMap;
jsp中
<input name="userMap['m1']"/>
<input name="userMap['m2']"/>
springmvc中
使用直接在返回写上对应的数据类型,直接使用不解释,其中你可以对httpServletRequest,HttpServletResponse,HttpSession,model/modelMap书写到参数列表中直接使用
4.自定义类型转换器与自定义拦截器
自定义类型转换
struts2
局部的类型转换器
1.自定义转换器继承StrutsTypeConverter
2.重写converFromString和converToString方法
3.注册转换器
1.在action所在包中建立
action名-conversion.properties
添加以下数据
需要转换的字段名=自定义转换器类的权限定名
born=com.zhenzhigu.convertor.DateTypeConvertor
全局类型转换器
实现步骤:
1.自定义转换器继承strutsTypeConverter
2.重写convertFromString和convertToString方法
3.注册转换器
1.在项目src目录下建立以下固定文件
Xwork-conversion.properties
2.添加以下数据
需要转换的类类型=转换类的权限定名
如:java.util.Date=com.zhenzhigu.converter.DateConverter
springmvc中
直接全局
自定义类型需要实现Converter
如日期类型转换
public class DateConverter implements Convert<String,Date>{
@Override
public Date convert(String source){
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
//转成直接返回
return simpleDateFormat.parse(source);
}catch(ParseException e){
e.printStackTrace();
}
return null;
}
}
springmvc.xml配置文件中
<!-- 自定义参数绑定 -->
<bean id="conveter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 转换器 -->
<property name="converters">
<list>
<!-- 日期类型转换 -->
<bean class="com.zhenzhigu.ssm.controller.converter.CustomDateConverter"/>
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="conveter"></mvc:annotation-driven>
自定义拦截器
struts2中
struts2中所有的自定义拦截器都需要实现interceptor接口
每拦截一个动作请求,该方法会被调用一次interceptor方法
<package name="test" name="/test" extends="struts2-default">
<interceptors>
<interceptor name="myInterceptor" class="com.zhenzhigu.aop.MyInterceptor"></interceptor>
<interceptor-stack name="myStack">
<intercetpro-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myInterceptor">
</interceptor-ref>
</interceptor-stack>
</interceptors>
通知struts2执行自定义的拦截栈,覆盖struts.default 中配置
<default-interceptor-ref name="myStack"/>
</package>
ActionInvocation:代表一个给定action状态,拦截器调用invoke方法进到action处理流程的下一个环节
执行流程是用户访问将要被拦截的请求
(继承了interceptor接口),执行拦截器
springmvc中
定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
<ref bean="handlerInterceptor2"/>
</list>
</property>
</bean>
<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>
ps:BeanNameUrlHandlerMapping就是,处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url)
所有的映射器都实现 HandlerMapping接口。
而另一种简单url映射:写法的例子是<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- 对itemsController1进行url映射,url是/queryItems1.action -->
<prop key="/queryItems1.action">itemsController1</prop>
<prop key="/queryItems2.action">itemsController1</prop>
<prop key="/queryItems3.action">itemsController2</prop>
</props>
</property>
</bean>
类似全局的拦截器
springmvc框架将配置的类型全局的拦截器注入到每一handlerMapper中
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.zhanzhigu.interceptor.HandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
public class LoginInterceptor implements HandlerInterceptor {
...
}
补充servlet中的过滤器
首先你的过滤器需要实现Filter接口
而后重写doFileter方法实现业务逻辑操作,而后chain.doFileter()方法执行下一步的操作
public class HelloFilter implements Filter{
// 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作,
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("3. 执行过滤器业务处理方法");
// 放行 (去到Servlet)
// 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
chain.doFilter(request, response);
System.out.println("5. Servlet处理完成,又回到过滤器");
}
}
5.使用servlet的元素
struts2中
首先struts2对HttpServletRequest、HttpSession和ServletContext进行了封装,构造3个Map对象来替代3个对象,在action中可以直接使用HttpServletRequest,HttpSession,ServletContext对象的Map对象来保存和读取数据,访问的方式是使用ServletActionContext
传统的访问方式是
public class ServletAction extends ActionSupport{
//获取request对象
HttpServletRequest request=ServletActionContext.getRequest();
//获取response对象
HttpServletResponse response=ServletActionContext.getResponse();
//获取session对象
HttpSession session=request.getSession();
//获取context对象
ServletContext context=ServletACtionContext.getServletContext();
}
当然同时也可以使用拦截器的方式进行访问
struts2中map访问方式(对原始对象进行封装后形成的map)
public class TestAction extends ActionSupport{
public void test(){
//获取struts2封装request后形成的map对象
ActionContext actionContext=ServletActionContext.getContext();
//获取struts2封装session后形成的数据对象
Map<String,Object> session=actionContext.getSession();
//获取struts2中获取的context对象
Map<String,Object> application=actionContext.getApplication();
}
}
springmvc中
可以要使用的servlet内容放到绑定参数的方法中
HttpServletRequest,HttpServeltResponse,HttpSession
6.访问域中的元素
struts2中
使用的方式有ognl表达式,jstl加el表达式,原生的java代码
如果你要使用ongl则需要配合struts2的标签
说一下ognl优势
1.支持对象方法调用
2.支持类静态的方法调用和值访问,表达式的格式
@[类全名(包括路径)]@[方法名|值名],例如
3.支持赋值操作和表达式串联
4.访问ognl上下文(ognl context)和actioncontext
5.操作集合对象
值栈的理解
valuestack贯穿整个action的生命周期(每一个action类的对象实例都有一个valuestack对象)相当于一个数据的中转站,在其中保存当前action对象和其它相关对象。
valuestack中包含
list栈与map栈
其中map栈中包含一个索引_roo指向list栈中,如此以后访问元素,可以直接访问map栈
访问不同栈使用的方式是
使用#对map栈的访问
不带#默认对象map栈进行访问
。。。。。
springmvc中
jstl加el表达式,原生的java代码
7.转发与重定向
两者都有
转发
request.getRequestDispatcher("/student_list.jsp").forward(request, response);
重定向
response.sendRedirect(request.getContextPath() + "/student_list.jsp");
返回json字符串
Response.setCharacterEncoding(“utf-8”);
Response.setContentType(“application/json;charset=utf-8”);
Response.getWriter().writer(“json串”);
struts2中
action跳转携带参数(站内)
从一个action直接跳到另一个action中,struts提供了两种结果类型可以实现:chain,redirect.
两者的区别在于chain可以保存参数,而redirect则不可以。
http://blog.csdn.net/chenssy/article/details/7960599
写法:<package name="mystruts1" extends="struts-default" namespace="/mystruts1">
<!-- 第一个Action -->
<action name="test_*" class="com.action.TestAction" method="{1}">
<result name="text_chain" type="chain">result_resultChain</result>
<result name="text_redirect" type="redirect">result_resultRedirect</result>
</action>
<!-- 第二个Action -->
<action name="result_*" class="com.action.ResultAction" method="{1}">
</action>
</package>
当然不是绝对的使用另一种方法可以实现redirect带参数
写法<result name=”success” type=”redirectAction”>
<param name=”actionName”>testAction</param>
<param name=”id”>${id}</param>//从这个action的值栈中取值
</result>
springmvc中
redirect重定向
return "redirect:test.action";
可以跳转到百度写法“http://www.baidu.com“使用?key=value传递参数
forwared页面转发
return "forward:test.action"
8.文件的上传与下载
文件上传
struts2中
public class UploadAction extends ActionSupport{
//定义文件对象,多个文件写成数组
private File file;
//保存文件上传类型:该变量的定义必须是上传表单file字段的name属性值+ContentType
//保存上传文件名:该变量的定义必须是上传表单file字段的name属性值+Filename
public String upload(){
//读取临时文件存储即可,这样的写法导致应用重新起动导致图片丢失
String dir=ServletActionContext.getServletContext().getRealPath("/fileupload");
File destFile=new File(dir,fileFileName);
try{
}catch(IOException e){
//如果异常,框架会跳转到input指定的jsp
e.printStackTrace();
}
}
return "success";
}
struts2.xml中文件的配置
<action name="uploadaction" class="upload" method="upload">
<!--引用默认栈-->
<interceptor-ref>
<!--设置默认栈中-->
<param name="fileupload.maximumSize">1000000</paran>
<!--貌似这个参数不太好用,但是下面的是只能上传图片的格式写法-->
<param name="fileupload.allowedTypes">image/png,image/jpeg,image/jpg,
image/pjpeg ,image/bmp, image/gif, image/x-png</param>
<param name="fileupload.allowedExtensions">png,jpg,gif</param>
</interceptor>
</action>
springmvc中
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
....方法形参
如果你想批量上传请将此写成数组
public String upload(MultipatFile file) throws Exception{
}
//原始名称
String originalFilename =file.getOriginalFilename();
//上传图片
if(items_pic!=null && originalFilename!=null && originalFilename.length()>0){
//存储图片的物理路径
String pic_path = "F:\\develop\\upload\\temp\\";
//新的图片名称
String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
//新图片
File newFile = new File(pic_path+newFileName);
//将内存中的数据写入磁盘
items_pic.transferTo(newFile);
//将新图片名称写到destfile中
destfile.setPic(newFileName);
}
下载文件
struts2中
// 1. 获取要下载的文件的文件名
private String fileName;
public void setFileName(String fileName) {
// 处理传入的参数中问题(get提交)
try {
fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// 把处理好的文件名,赋值
this.fileName = fileName;
}
//2. 下载提交的业务方法 (在struts.xml中配置返回stream)
public String down() throws Exception {
return "download";
}
// 3. 返回文件流的方法
public InputStream getAttrInputStream(){
return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
}
// 4. 下载显示的文件名(浏览器显示的文件名)
public String getDownFileName() {
// 需要进行中文编码
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return fileName;
}
<action name="down_*" class="com.zhenzhigu.e_fileupload.DownAction" method="{1}">
<!-- 列表展示 -->
<result name="list">/e/list.jsp</result>
<!-- 下载操作 -->
<result name="download" type="stream">
<!-- 运行下载的文件的类型:指定为所有的二进制文件类型 -->
<param name="contentType">application/octet-stream</param>
<!-- 对应的是Action中属性: 返回流的属性【其实就是getAttrInputStream()】 -->
<param name="inputName">attrInputStream</param>
<!-- 下载头,包括:浏览器显示的文件名 -->
<param name="contentDisposition">attachment;filename=${downFileName}</param>
<!-- 缓冲区大小设置 -->
<param name="bufferSize">1024</param>
</result>
</action>
springmvc中
public ResponseEntity<byte[]> testDownload(String fileName) throws IOException {
String dfileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", dfileName);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}
9.数据校验
struts2表单数据校验
手工方式
jsp中显示校验错误显示的消息
1. Action继承ActionSupport(提供和表单同名的属性以及get和set)
2. 重写validate方法
3. 使用this.addFieldError(“username”, “用户名不能为空!”);添加校验信息
4. 使用<s:fielderror fieldName=“username” />显示指定校验信息
校验方法执行 setXXX()->validate()->execute同类方法
默认validate()校验action中的所有方法,如果用户单击注册超链接访问注册页面的时候该方法就会执行校验无法跳转。所以需要重写validateXXX()如果只是需要校验login方法那么就是validateLogin()
// 重写数据验证的方法
public void validateRegister() {
// 用户名非空
if (user.getUserName() == null || "".equals(user.getUserName())) {
// 保存错误信息
super.addFieldError("userName", "用户名必须填写!");
}
// 密码
if (user.getPwd() == null || "".equals(user.getPwd())) {
super.addFieldError("pwd", "密码必填");
}
}
// 业务方法
public String register() {
System.out.println(user);
System.out.println(1);
return SUCCESS;
}
xml配置方式
1. 命名方式ActionClassName-validation.xml 放置在同Action的包下,引入DTD规范
的时候参见0步骤中的约束文件
2配置
<validators>
<field name="username">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>用户名不能为空</message>
</field-validator>
</filedl-validator>
</validators>
!!!指定方法配置验证器
action类名-name属性名-validatin.xml.(name属性名:在strtus配置文件中的)
内置数据校验
。。。。。。。。
springmvc中
页面叫提交请求参数,请求道controller方法中,使用validation进行校验。如果出错,将错误信息展示到页面
在springmvc.xml文件中配置
<!-- 校验器 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- hibernate校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean>
<!-- 校验错误信息配置文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 资源文件名-->
<property name="basenames">
<list>
<value>classpath:CustomValidationMessages</value>
</list>
</property>
<!-- 资源文件编码格式 -->
<property name="fileEncodings" value="utf-8" />
<!-- 对资源文件内容缓存时间,单位秒 -->
<property name="cacheSeconds" value="120" />
</bean>
<mvc:annotation-driven conversion-service="conversionService"
validator="validator"></mvc:annotation-driven>
pojo中添加校验规则
public class user{
private Integer id;
//校验名称在1到30字符中间
@Size(min=1,max=30,message="{user.name.length.error}")
private String name;
}
CustomValidationMessages.properties文件中书写
user.name.length.error=请输入的用户名在10个字符之内
捕获校验错误信息
@RequestMapping("/test")
public String testUser(HttpServletRequest request,Integer id,@Validated User user,BindingResult bindResult) throws Exception{
if(bindResult.hasErrors()){
List<ObjectError> allErrors=bindingResult.getAllError();
for(ObjectError objectError:allErrors){
System.out.println(objectError.getDefaultMessage());
}
//显示错误信息到页面上
model.addAttribute("allErrors",allErrors);
return "home/index.jsp";
}
}
分组校验
pojo的校验规则用于多个controller时的处理手段
实现步骤
定义多个校验分组(一个java接口,不定义任何方法)
在写校验规则时后面加上groups={group1.class}字段内容
新的校验规则是
@Size(min=1,max=30,message="{user.name.length.error}",groups={group1.class})
controller中使用是
@RequestMapping("/test")
public String testUser(@Validateged(value={group1.class}) User user,BindingResult bindResult) throws Exception{
....
}
10.整合freemark
struts2中
在struts2中整合freemark
需要将struts2-core-xxx.jar文件,把在META-INF文件夹下面的struts-tags.tld文件复制到WEB-INF文件夹下。将freemark的jar导入到工程中
在web.xml文件中配置freemark同时启动JSPSupportServlet
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>
freemarker.ext.servlet.FreemarkerServlet
</servlet-class>
<!--下面的配置freemarke的ftl文件的位置 -->
<init-param>
<param-name>TemplatePath</param-name>
<param-value>/</param-value>
</init-param>
<!-- 是否和服务器(tommcat)一起启动。-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
<servlet>
<!-- define a JspSupportServlet Object -->
<servlet-name>JspSupportServlet</servlet-name>
<servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
<!-- setting JspSupportServlet auto start -->
<load-on-startup>1</load-on-startup>
</servlet>
3.在FreeMarker模板中使用assign指令导入标签库。代码如下
<#assign s=JspTaglibs["/WEB-INF/struts-tags.tld"] /> 注:这里我把struts-tags.tld放在WEB-INF下面
这样做以及第一步都是为了你可在freemark中使用struts2标签了
struts2.xml配置中写法是
<package name="default" extends="struts-default">
<action name="test" class="com.sxt.test.TestAction">
<result name="success" type="freemarker">test_success.ftl</result>
</action>
</package>
springmvc中
<!-- 一定要放在viewResolver的前面,这样就先去找freemarker的 -->
<!--配置freemark的配置文件-->
<!-- 配置freeMarker的模板路径 -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/view/" />
<!-- FreeMarker默认每隔5秒检查模板是否被更新,如果已经更新了,就会重新加载并分析模板。 但经常检查模板是否更新可能比较耗时。如果你的应用运行在生产模式下,而且你预期模板不会经常更新,
则可以将更新的延迟时间延长至一个小时或者更久。 可以通过为freemarkerSettings属性设置template_update_delay达到这一目的 -->
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">3600</prop>
<prop key="tag_syntax">auto_detect</prop><!-- 设置标签类型 两种:[] 和 <> 。[] 这种标记解析要快些 -->
<prop key="default_encoding">UTF-8</prop>
<prop key="output_encoding">UTF-8</prop>
<prop key="locale">zh_CN</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="time_format">HH:mm:ss</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="number_format">#</prop><!-- 设置数字格式 以免出现 000.00 -->
<prop key="classic_compatible">true</prop><!-- 可以满足一般需要。默认情况变量为null则替换为空字符串,如果需要自定义,写上${empty!"EmptyValue of fbysss"}的形式即可 -->
<prop key="template_exception_handler">html_debug</prop><!-- ignore,debug,html_debug,rethrow -->
</props>
</property>
</bean>
<!-- 配置freeMarker视图解析器 -->
<!-- FreeMarker视图解析 如返回student,在这里配置后缀名ftl和视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
<property name="cache" value="true"/>
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="requestContextAttribute" value="request" />
<!-- 将请求和会话属性作为变量暴露给FreeMarker模板使用。要做到这一点,可以设置exposeRequestAttributes或者exposeSessionAttributes为true -->
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<!-- 使用这些宏,必须设置FreeMarkerViewResolver的exposeMacroHelpers属性为true -->
<property name="exposeSpringMacroHelpers" value="true" />
</bean>
<bean
class="org.springframework.web.servlet
.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
另一种配置http://songjianyong.iteye.com/blog/1462208