跳至主要內容

JSP

Yang大约 15 分钟

Java Server Pages:Java 服务器页面

  • 是 J2EE 的功能模块,由 Web 服务器执行
  • JSP 的作用就是降低动态网页开发难度
  • 使用简单,易于上手
  • 将 Java 代码与 HTML 分离,降低开发难度
  • JSP 的本质就是 Servlet

运行要求

  • 可正常运行的 Tomcat
  • 所有的 JSP 页面扩展名必须是 .jsp
  • JSP 页面应放在 Web 应用程序目录下

执行过程

  • 浏览器访问 JSP(将请求发送给 Tomcat)
  • Tomcat 找到对应 JSP 文件,并将其转译为 Servlet 源码
  • Java 将 Servlet 源码编译为 Servlet 字节码(.class)
  • 字节码文件执行,将结果返回的 HTML 返回给浏览器

基本语法

注释

  • <%-- 注释 --%>:JSP 注释,被注释的语句不做任何处理
  • //、/*..*/:Java 代码注释 ,被注释的代码不执行
  • <!-- 注释 -->:HTML 注释,被注释的语句不会被浏览器解析

代码块

用于在 JSP 中嵌入 Java 代码

  • 语法:<% Java代码 %>
<% System.out.print("hello world"); %>

声明构造块

用于声明变量或方法

  • 语法:<%! 声明语句 %>
<%! public int add(int a, int b){ return a+b; } %>

指令 <%@ ... %>

page

用于提供在 JSP 执行过程中的辅助信息,如定义页面特定的属性(字符编码、响应内容类型一级页面是否要有隐式的会话对象)

  • 语法:<%@ page ... %>
属性描述
import导入要使用的 Java 类
contentType指定当前 JSP 页面的 MIME 类型和字符编码
errorPage指定当 JSP 页面发生异常时需要转向的错误处理页面
isErrorPage指定当前页面是否可以作为另一个 JSP 页面的错误处理页面
isELIgnored指定是否忽略 EL 表达式
isThreadSafe指定对 JSP 页面的访问是否为线程安全
extends指定 servlet 从哪一个类继承
info定义 JSP 页面的描述信息
buffer指定 out 对象使用缓冲区的大小
language定义 JSP 页面所用的脚本语言,默认是 Java
session指定 JSP 页面是否使用 session
autoFlush控制 out 对象的 缓存区
isScriptingEnabled确定脚本元素能否被使用
<!-- 导入包 -->
<%@ page import="java.util.*, java.io.*"%>

<!-- 设置页面属性 -->
<%@ page
  language="java"
  contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"
  session="false"
%>

include

将其他 JSP 页面与当前 JSP 页面合并

  • 语法:<%@ include file="header.jsp"%>

taglib

定义 JSP 可以使用的标签库

定义
<!-- MyFunction.tld 放在 WEB-INF 文件夹下 -->
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
	version="2.0">
	<tlib-version>1.2</tlib-version>
	<uri>DiceFunctions</uri>
	<function>
		<name>rollIt</name>
		<function-class>com.example.model.DiceRooler</function-class>
		<function-signature>int roolDice()</function-signature>
	</function>
</taglib>
// DiceRooler.java
package com.example.model;

public class DiceRooler {
	public static int roolDice() {
		return (int) ((Math.random() * 6) + 1);
	}
}
使用
  • <%@ taglib <%@ taglib uri="DiceFunctions" prefix="mine" tagdir="/WEB-INF/tags/cool">
    • uri:和 .tld 文件中的 <uri> 标签相对应
    • prefix:别名、前缀
    • tagdir.tld 文件存放路径
<!-- test.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%@ taglib prefix="mine" uri="DiceFunctions"%>
	<h1>${mine:rollIt()}</h1>
</body>
</html>

表达式 <%= ... %>

用于在 JSP 页面中显示 Java 代码执行的结果,out.print() 的简写形式(容器拿到 <%=%> 之间的内容,把它作为参数传递给打印语句,打印到隐式响应 PrintWrite out

  • 语法:<%= Java代码 %>
  • %= 之间不能有空格
<%= "<p>" + name + "</p>" %>
<!-- 相当于 -->
out.print("<p>" + name + "</p>");

JSP 声明 <%! ... %>

 用于声明所生成的 Servlet 类成员,变量和方法都可以生命,换句话说,标记之间的所有内容都会增加到类中,而且至于服务方法之外。这意味着完全可以声明静态变量和方法

<h1>
  <%!
  	public static int count = 0;
  	public static int countAddNumber(int num) {
      return count + num;
    }
  %>
  <%=++count%>
  <%=countAddNumber(10)%>
</h1>

动作

  • <jsp:include page="test.jsp">
  • <c:set var="rate" value="32">

jsp:useBean

声明和初始化一个 bean 属性,如果找不到一个名为 id 值的属性对象,就会创建一个

  • 语法
    • <jsp:useBean id="person" class="com.example.model.Person" scope="request" />
      • jsp:useBean:JSP 标准动作标识
      • id:声明 bean 对象的标识符,对应 servlet 中的 request.setAttribute("person", person)
      • type:可以是 class 类型、抽象类型、或者是一个接口,
      • class:声明 bean 对象的类类型(完全限制名),必须是 type 的一个子类或具体实现
      • scope:标识这个 bean 对象的属性作用域
    • <jsp:getProperty name="person" property="name" />
      • jsp:getProperty:JSP 标准动作标识
      • name:标识具体的 bean 对象,与 <jsp:useBean> 标记的 id 值匹配
      • property:表示属性中的性质名(也就是与 bean 类型中获取方法和设置方法对应的性质)
    • <jsp:setProperty name="person" property="name" value="sunzhenyang" />
      • param:请求参数名(input name)
<jsp:useBean id="person" class="com.example.model.Person" scope="request">
  <!-- jsp:useBean体中的代码会有条件的运行,只有找不到 bean 而且创建一个新 bean 时才会运行 -->
	<jsp:setProperty name="person" property="name" value="sunzhenyang" />
</jsp:useBean>

jsp:include

复制文件内容到另一个文件中,内部实现为动态复制

include 指令是只对第一次请求有效,但是很多容器也实现了动态复制

  • <jsp:include page="Footer.jsp" />

jsp:param

设置被包含文件的参数

  • 可以用在 jsp:includejsp:forward 标签中
<!-- Header.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<h1>This is 头部</h1>
<h1>${param.tip},${param.name}!</h1>
<!-- test.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<jsp:include page="Header.jsp">
		<jsp:param value="Hello" name="tip" />
		<jsp:param value="sunzhenyang" name="name" />
	</jsp:include>
	<h2>This is Content</h2>
	<jsp:include page="Footer.jsp" />
</body>
</html>

jsp:forward

转发到其他的 JSP 页面

  • <jsp:forward page="login.html" />
  • 转发时会先清空响应缓冲区,请求转发到的目标资源会先清空输出,所以转发前写至响应的所有内容都会清掉
<!-- test.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Welcome to our page.</h1>
	<%
		String username = request.getParameter("username");
		if (username == null || username.equals("")) {
	%>
	<jsp:forward page="login.jsp" />
	<%
		}
	%>
</body>
</html>
<!-- login.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="test.jsp">
		<input name="username" /> <input type="submit" value="提交" />
	</form>
</body>
</html>

内置对象

可直接在 <% %> 中使用,页面级作用域

内置(隐式)对象API描述
requestHttpServletRequest请求对象 - HttpServletRequest
responseHttpServletResponse响应对象 - HttpServletResponse
sessionHttpSession用户会话 - HttpSession
applicationServletContext应用全局对象 - ServletContext
outJspWriter输入对象 - PrintWrite
pageObject当前页面对象 - this
pageContextPageContext页面上下文对象 - PageContext
configServletConfig应用配置对象 - ServletConfig
exceptionThrowable应用异常对象 - Throwable
  • PageContext 封装了其他隐式对象,所以如果像某些辅助对象提供了一个 PageContext 引用,这些辅助对象就可以用这个 PageContext 引用得到其他隐式对象的引用以及所有作用域的属性
  • JspWriter 不在 PrintWrite 的类层次中,所以不能用来取代 PrintWrite,不过它的大多数打印方法都与 PrintWrite 相同,只不过增加了一些缓冲功能
<!-- exception -->
<%
	String msg = exception.getMessage();
	out.print("<br>" + exception.getClass().getSimpleName() + ":" + msg);
%>

PageContext

可以使用 PageContext 引用来得到任意作用域的属性,包括从页面作用域得到绑定到 PageContext 的属性

访问其他作用域的方法要取一个 int 参数,这个参数用来指示是哪一个作用域,尽管属性存取方法在 JspContext 中,但作用域常量在 PageContext

JspContext

  • getAttribute(String name)
  • getAttribute(String name, int scope)
  • getAttributeNamesInScope(int scope)
  • findAttribute(String name)
  • 更多方法:包括以上获取方法类似的设置和删除方法,可以设置和删除任意作用域中的属性

PageContext

继承自 JspContext

  • 字段
    • APPLICATION_SCOPE:int
    • PAGE_SCOPE:int
    • SESSION_SCOPE:int
    • REQUEST_SCOPE:int
    • ...
  • 方法
    • getRequest()
    • getServletConfig()
    • getServletContext()
    • getSession()
    • ...
<%
	// 设置页面作用域属性
  pageContext.setAttribute("name1", "value1");
	// 设置应用作用域属性
  pageContext.setAttribute("name2", "value2", PageContext.APPLICATION_SCOPE);
	// 设置会话作用域属性
  pageContext.setAttribute("name3", "value3", PageContext.SESSION_SCOPE);
	// 设置请求作用域属性
  pageContext.setAttribute("name4", "value4", PageContext.REQUEST_SCOPE);
%>
<!-- 获取页面作用域属性 -->
<h1><%=pageContext.getAttribute("name1")%></h1>
<!-- 获取应用作用域属性 -->
<h1><%=application.getAttribute("name2")%></h1>
<!-- 获取会话作用域属性 -->
<h1><%=session.getAttribute("name3")%></h1>
<!-- 获取请求作用域属性 -->
<h1><%=request.getAttribute("name4")%></h1>

初始化参数

设置参数

<!-- web.xml -->
<servlet>
	<servlet-name>MyTestInit</servlet-name>
  <jsp-file>/MyTestInit.jsp</jsp-file>
  <init-param>
			<param-name>username</param-name>
			<param-value>sunzhenyang</param-value>
		</init-param>
		<init-param>
			<param-name>age</param-name>
			<param-value>28</param-value>
		</init-param>
		<init-param>
			<param-name>sex</param-name>
			<param-value></param-value>
		</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>MyTestInit</servlet-name>
  <url-pattern>/MyTestInit.jsp</url-pattern>
</servlet-mapping>

获取参数

<!-- 综合运用 -->
<%!public void jspInit() {
  System.out.println("JSP初始化");
  ServletConfig sConfig = getServletConfig();
  String username = sConfig.getInitParameter("username");
  String age = sConfig.getInitParameter("age");
  String sex = sConfig.getInitParameter("sex");
  System.out.println(username + " - " + age + " - " + sex);
  ServletContext context = getServletContext();
  context.setAttribute("username", username);
  context.setAttribute("age", age);
  context.setAttribute("sex", sex);
}%>
<h1><%=application.getAttribute("username")%></h1>
<h1><%=application.getAttribute("age")%></h1>
<h1><%=application.getAttribute("sex")%></h1>

<!-- 直接获取 -->
<h1><%=config.getInitParameter("username")%></h1>
<h1><%=config.getInitParameter("age")%></h1>
<h1><%=config.getInitParameter("sex")%></h1>

禁止脚本元素

禁止 scriptlet、Java 表达式或声明

<web-app>
  <jsp-config>
      <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <scripting-invalid>true</scripting-invalid>
      </jsp-property-group>
  </jsp-config>
</web-app>

忽略 EL 表达式

可以通过 page 指令,也可以通过 web.xml,如果两种方式有冲突,则以 page 指令为准

  • <%@ page isELIgnored="true" %>
<web-app>
  <jsp-config>
      <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <el-ignored>true</el-ignored>
      </jsp-property-group>
  </jsp-config>
</web-app>

生命周期

jspInit()

可以覆盖,由 Servletinit() 方法调用

<!-- 覆盖 jspInit 方法 -->
<%!
  public void jspInit() {
    System.out.println("JSP 初始化调用");
  }
%>

jspDestory()

可以覆盖,由 Servletdestroy() 方法调用

<!-- 覆盖 jspInit 方法 -->
<%!
			public void jspInit() {
				System.out.println("JSP 初始化调用");
			}

			public void jspDestroy() {
				System.out.println("JSP 销毁时调用");
			}
		%>

jspService()

不可覆盖

EL 表达式

用于简化 JSP 输出

  • 语法:${[作用域.]属性名[.子属性]}
  • 支持将运算结果进行输出
  • 支持绝大多数对象输出,本质是执行 toString() 方法

作用域对象

如果忽略书写作用域对象时,EL 则会按作用域从小到大依次尝试获取,如果都没有匹配 ,则会返回空字符串

pageContext 之外,其他的只是 Map

作用域对象描述
pageScope从当前页面取值
requestScope从当前请求中获取属性值
sessionScope从当前会话中获取属性值
applicationScope从当前应用获取全局属性值
param请求参数
paramValues请求参数(有多个参数值时)
header请求头部
headerValues
cookie
initParam上下文初始化参数 <context-param>
pageContextpageContext 对象的引用

示例

// Student.java
package com.imooc.el;

public class Student {
	private String name;
	private String mobile;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

}
// StudentServlet.java
package com.imooc.el;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class StudentServlet
 */
@WebServlet("/info")
public class StudentServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public StudentServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Student student = new Student();
		student.setName("张三");
		student.setMobile(null);
		request.setAttribute("student", student);
		request.setAttribute("grade", "A");
		request.getRequestDispatcher("/info.jsp").forward(request, response);
	}
}
<!-- 普通写法 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" import="com.imooc.el.Student"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		Student stu = (Student) request.getAttribute("student");
		String grade = (String) request.getAttribute("grade");
	%>
	<h1>
		姓名:<%=stu.getName()%></h1>
	<h2>
		手机:<%=stu.getMobile()%></h2>
	<h2>
		评级:<%=grade%></h2>
</body>
</html>

<!-- EL表达式写法 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>姓名:${requestScope.student.name}</h1>
	<h2>手机:${requestScope.student.mobile}</h2>
	<h2>评级:${requestScope.grade}</h2>
</body>
</html>

请求参数简化

使用 param 对请求参数进行简化

<!-- url: http://***.com?teacher=Yang -->
<h1>
  ${param.teacher}
</h1>

操作符

算数操作符

描述操作符
加法+
减法-
乘法*
除法/div
取模%mod

逻辑操作符

| 描述 | 操作符 |
| ---- | ------------- | --- | ------- |
| 与 | &&and |
| 或 | | |or |
| 非 | !not |

关系操作符

描述操作符
等于==eq
不等于!=ne
小于<lt
大于>gt
小于等于<=le
大于等于>=ge

注意

  • 可以除 0 ,得到 Infinity

  • 不能对 0 使用取模操作符,会抛出异常

  • 会妥善处理 null 而不会抛出异常,不同表达中未定义的变量不会打印

  • 算数表达式中,把未知变量替换为 0

  • 逻辑表达式中,把未知变量替换为 false

JSTL 标签库

JSP Standard Tag Library:JSP 标准标签库

  • 用于简化 JSP 开发,提高代码的可读性与可维护性
  • 由 SUN(Oracle)定义规范,有 Apache Tomcat 团队实现

下载

下载地址:Apache Standard Taglib 1.2.5open in new window

作用域对象描述
taglibs-standard-spec-1.2.5.jar标签库定义包(必选)
taglibs-standard-impl-1.2.5.jar标签库实现包(必选)
taglibs-standard-jstlel-1.2.5.jarEL 表达式支持包(备选)
taglibs-standard-compat-1.2.5.jar1.0 版本兼容包(备选)

标签库种类

  • core:核心标签库
    • taglibs-standard-impl.jarMETA-INF/c.tld 定义
  • fmt:格式化输出标签库
  • sql:SQL 操作标签库
  • xml:XML 操作标签库
  • functions:函数标签库

安装

方式一(推荐)

  • Jar 文件复制到工程的 /WEB-INF/lib 目录
  • Eclipse 会自动将复制到工程 /WEB-INF/lib 目录的文件加入到 Java resources -> Libraries -> Web App Libraries 目录

方式二

  • Jar 文件复制到 Tomcat 的 lib 目录

引入

Eclipse 中 按 Alt + / 出现智能提示

<!-- c:core  fmt:fmt -->

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

使用

设置默认值

<c:out>

  • 参数
    • value:要使用的变量
    • default:点变量值为 null 时显示的默认值
<c:out value="${nothing}" default="无"></c:out>

输出 HTML 源代码

<c:out />

  • 参数
    • value:要使用的变量
    • escapeXml:是否转义特殊字符
<%
	request.setAttribute("html", "<a href='index.html'>index</a>");
%>
<h3>
  特殊字符:
  <c:out value="${html}" escapeXml="true" />
</h3>

单分支判断

<c:if>

<h1>分数:${requestScope.score}</h1>
<c:if test="${requestScope.score >= 60}">
  <h1 style="color: green;">恭喜,你已通过测试</h1>
</c:if>
<c:if test="${requestScope.score < 60}">
  <h1 style="color: red;">对不起,再接再厉</h1>
</c:if>

多分支判断

<c:choose><c:when><c:otherwise>

<h1>评级:${requestScope.grade}</h1>
<c:choose>
  <c:when test="${requestScope.grade == 'A'}">
    <h1 style="color: green;">优秀</h1>
  </c:when>
  <c:when test="${requestScope.grade == 'B'}">
    <h1 style="color: green;">良</h1>
  </c:when>
  <c:when test="${requestScope.grade == 'C'}">
    <h1 style="color: green;">一般</h1>
  </c:when>
  <c:otherwise>
    <h1 style="color: red;">差</h1>
  </c:otherwise>
</c:choose>

遍历集合

<c:forEach>

  • 参数
    • items:要循环的列表
    • var:循环中的元素
    • varStatus:变量状态
      • index:索引
      • count:技术
<c:forEach items="${requestScope.companies}" var="c" varStatus="idx">
  <h1>${idx.index+1}.&nbsp;${c.cname}&nbsp;${c.url}</h1>
</c:forEach>

日期格式化

<fmt:formatNumber />

  • 参数
    • value:要格式化的值
    • pattern
      • yyyy:四位年
      • MM:两位月
      • dd:两位日
      • HH:24 小时制
      • mm:分钟
      • ss:秒数
      • SSS:毫秒
<% request.setAttribute("now", new java.util.Date()); %>
<h3>
  时间格式化:
  <fmt:formatDate value="${requestScope.now}"
                  pattern="yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒" />
</h3>

数字格式化

<fmt:formatNumber />

参数

  • value:要格式化的值
  • pattern:保存的小数位样式
    • 0.00:保存两位小数
    • 0,00.00:按百分位切割
    • 0,000.00:按千分位切割
<% request.setAttribute("amt", 1987654.326); %>
<h3>
  数字格式化:
  <fmt:formatNumber value="${requestScope.amt}" pattern="0,000.00" />
</h3>

模板引擎

将数据与展现解耦

主流模板引擎

  • Java Server Page(JSP)
  • Freemarker
  • Beetl

Freemarker

免费开源的模板引擎技术,脚本为 FTL(Freemarker Template Language)

语法

取值
  • ${属性名}:取值,可对属性进行计算(不存在的属性会报错)
  • ${属性名!默认值}:使用默认值
if 分支
<#if 条件1>
	条件1成立执行代码
<#elseif 条件2>
	条件2成立执行代码
<#elseif 条件3>
	条件3成立执行代码
<#else>
	其他情况下执行代码

<#if a==b>
<#if computer.user??></#if> 判断对象是否为空
switch 分支
<#switch value>
	<#case refValue1>
		...
		<#break>
	<#case refValue2>
		...
		<#break>
	<#case refValueN>
		...
		<#break>
	<#default>
		...
</#switch>
list 迭代列表
// stu_index 默认循环索引

<#list students as stu>
	<li>${stu_index}-${stu.name}</li>
</#list>

<#list mapDate?keys as k>
	<li>${k}${mapDate[k]}</li>
</#list>
内建函数
函数名说明示例
lower_case/upper_case大小写转换"abcdefg"?upper_case
cap_first首字母大写"jackson"?cap_first
index_of查找字符索引abcdefg?inde_of("b")
length返回字符串长度abcdefg?length
replace替换字符串str.replace("abcdefg","******")
round/floor/ceiling四舍五入/下取整/上取整pi?floor
size得到集合元素总数students?size
first/last获取 第一个/最后一个 元素students?first
sort_by("str")按某个属性对集合排序(加上 ?reverse 可以变为倒序)list?sort_by("time")

freemarker 与 servlet

<!-- Servlet 别名 -->
<servlet>
  <servlet-name>freemarker</servlet-name>
  <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
  <init-param>
  	<param-name>TemplatePath</param-name>
    <param-value>/WEB-INF/ftl</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>freemarker</servlet-name>
  <url-pattern>*.ftl</url-pattern>
</servlet-mapping>

案例

  • 新建 Java 项目 -> 新建 lib 文件夹 -> 放入 freemarker.jar -> build path
// FreemarkerSample1.java
package com.imooc.freemarker;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;

public class FreemarkerSample1 {

	public static void main(String[] args) throws TemplateNotFoundException, MalformedTemplateNameException,
			ParseException, IOException, TemplateException {
		// 1. 加载模板
		// 创建核心配置对象
		Configuration config = new Configuration(Configuration.VERSION_2_3_31);
		// 设置加载目录(第二个参数,空字符串表示当前包)
		config.setClassForTemplateLoading(FreemarkerSample1.class, "");
		// 得到模板对象
		Template t = config.getTemplate("sample1.ftl");

		// 2. 创建数据
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("site", "百度");
		data.put("url", "http://www.baidu.com");
		data.put("date", new Date());
		data.put("number", 837138.88523641);

		// Map数据
		Map info = new HashMap();
		info.put("cpu", "i5");

		// 自定义类数据
		Computer c1 = new Computer("XC13256", "C型", info);
		data.put("computer", c1);
		// 3. 产生输出
		t.process(data, new OutputStreamWriter(System.out));
	}
}
<#-- 取值 -->
${site}
${url}

<#-- 默认值 -->
${author!"不存在的属性"}

<#-- ?string格式化输出 -->
${date?string("yyyy-MM-dd HH:mm:ss SSS")}
${number?string("0.00")}
${number?string("0,00.00")}
${number?string("0,000.00")}

SN: ${computer.sn}
型号: ${computer.model}

CPU: ${computer.info["cpu"]}

<#-- 利用 ?string 实现三木运算符操作 -->
${words?index_of("abc") != -1?string("包含","不包含")}

打包与发布

  • Java Web 应用采用 war 包进行发布
  • 发布路径:{TOMCAT_HOME}/webapps
  • Eclipse 支持 war 包导出
    • File -> export -> Web(WAR file)->
    • 将打包后的 *.war 文件复制到 Tomcat 根目录
    • 进入 Tomcat -> bin 文件夹,运行 startup.sh
    • Tomcat 启动并自动解压 *.war

去掉访问路径中的端口号

<!-- Tomcat -> conf -> server.xml  -->
<!-- 80 为 http 默认端口号  -->
<Connector port="80" />

去掉访问路径中的文件夹

<!-- Tomcat -> conf -> server.xml  -->
<Context path="/" />
上次编辑于:
贡献者: sunzhenyang