到目前为止我们还没有集成Struts,如果我们想做动态页面,而用不想像Servlet一样把html标签写在java代码里面,也不想像Jsp一样把Java代码和html标签混在一起,那么我们可以试一下FreeMarker。
1、FreeMarker简介
FreeMarker是一款模板引擎:即一种基于模板、用来生成输出文本(任何来自于HTML格式的文本用来自动生成源代码)的通用工具。它是为Java程序员提供的一个开发包,或者说是一个类库。它不是面向最终用户的,而是为程序员提供的一款可以嵌入他们所开发产品的应用程序。
FreeMarker实际上是被设计用来生成HTML页面,尤其是通过实现了基于MVC(Model View Controller,模型-视图-控制器)模式的Java Servlet应用程序。使用MVC模式的动态页面的设计构思使得你可以将前端设计师(编写HTML页面的人员)从程序员中分离出来。那么,所有人各司其职,发挥其最擅长的一面。网页设计师可以改写页面的显示效果而不受程序员编译代码的影响,因为应用程序的逻辑(这里是Java程序)和页面设计(这里是FreeMarker模板)已经被分开了。页面模板代码不会受到复杂程序代码的影响。这种分离的思想即便对一个程序员和页面设计师是同一个人的项目来说也都是非常有用的,因为分离使得代码保持简洁而且易于维护。
尽管FreeMarker也拥有一些编程能力,但是它却不像PHP那样,是的一种全面的编程语言。反而,Java程序准备的数据来进行显示(比如SQL数据库查询),FreeMarker仅仅是使用模板生成文本页面来呈现已经准备好的数据而已。
FreeMarker不是Web开发的应用程序框架。它是一个适用于Web应用程序框架中的组件,但是FreeMarker引擎本身并不知道HTTP协议或Java Servlet的存在。它仅仅来生成文本内容。既然是这样,它也非常适用于非Web应用程序的开发环境。只是要注意的是,我们使用FreeMarker作为视图层的组件,是为了给诸如Struts这样的Model 2应用框架提供现成的解决方案。
FreeMarker本身是免费的,它基于BSD规则的许可协议。它也是OSI认证的开源软件。OSI认证是开源倡议的认证标识。
2、Servlet环境搭建
我们还是使用web.xml来配置servlet,而不是使用标注的方式--servlet 3.0的新特性。一个最简单的例子,后面集成FreeMarker的时候。
java代码
public class FreeMarkerServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 5012497548178271844L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println("<html><head><title>Welcome</title></head><body>");
out.println("Hello," + req.getParameter("name"));
out.println("</body></html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req,resp);
}
}
Note:不要调用super.get(),这样会得到405错误,告诉你不支持GET/POST方法。
servlet配置
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>grucee.freemarker.test.FreeMarkerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
Note:servlet的访问url就是http://localhost:8080/${application-context}${url-pattern}
html页面
<form action="LoginServlet" method="post">
Name:<input type="text" name="name"></input>
<input type="submit"></input>
</form>
Note:action如果不是以/开头,表示是一个相对地址,相对的就是你当前的应用程序,提交时会自动加上你的应用程序的context。
如果以/开头,表示是绝对地址,提交是就不会加应用程序的context,本例中就会是http://localhost:8080/LoginServlet,是访问不到我们应用的servlet的。当然你也可以显示的在action中包含应用程序的context,如action="/${application-context}/LoginServlet。
3、集成FreeMarker
- 下载FreeMarker的jar包,放在项目的lib目录下面
- 编写ftl文件,放在项目的WEB-INF/resource目录下面
- 修改Servlet代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获取请求传过来的name
String name = req.getParameter("name");
//获取应用程序的实际路径
String appPath = getServletContext().getRealPath("/");
//FreeMarker处理:构造Configuration对象
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File(appPath+ "/WEB-INF/resource"));
cfg.setObjectWrapper(new DefaultObjectWrapper());
//FreeMarker处理:设置数据模型,此处也可以用Map
RegistInfoBean bean = new RegistInfoBean();
bean.setName(name);
//获取模板
Template template = cfg.getTemplate("welcome.ftl");
PrintWriter out = resp.getWriter();
try {
//使用数据模型,处理模板ftl文件,输出到输出流中
template.process(bean, out);
} catch (TemplateException e) {
e.printStackTrace();
}
out.flush();
out.close();
}