Spring MVC 学习总结之FreeMarker模板引擎与动态页面静态化

目录

    一、FreeMarker简介
    二、第一个FreeMark示例
        2.1、新建一个Maven项目
        2.2、添加依赖
        2.3、添加存放模板的文件夹
         2.4、添加模板
        2.5、解析模板
        2.6、运行结果
    三、动态页面静态化
        3.1、动态页面静态化的优点
        3.2、动态页面静态化的问题
        3.3、实现动态页面静态化
            3.3.1、新建一个基于Maven的Web项目
            3.3.2、添加依赖
            3.3.3、创建文章POJO类
            3.3.4、创建文章业务类
            3.3.5、添加模板
            3.3.6、添加Servlet生成静态页
            3.3.7、运行结果
    四、FreeMarker模板语法
        4.0、模板文件的4个组成部分
        4.1、FTL指令规则
        4.2、 插值规则
        4.3、表达式
            4.3.1、直接指定值
            4.3.2、输出变量值
            4.3.3、字符串操作
            4.3.4、集合连接运算符
            4.3.5、Map连接运算符
            4.3.6、算术运算符
            4.3.7、比较运算符
            4.3.8、逻辑运算符
            4.3.9、内建函数
            4.3.10、空值处理运算符
            4.3.11、运算符的优先级
        4.4、FreeMarker的常用指令
            4.4.1、if指令
            4.4.2、switch , case , default , break指令
            4.4.3、list, break指令
            4.4.4、include指令
            4.4.5、import指令
            4.4.6、noparse指令
            4.4.7、escape , noescape指令
            4.4.8、assign指令
            4.4.9、setting指令
            4.4.10、macro , nested , return指令
    五、示例下载

模板引擎可以让程序实现界面与数据分离,业务代码与逻辑代码的分离,这就提升了开发效率,良好的设计也使得代码复用变得更加容易。一般的模板引擎都包含一个模板解析器和一套标记语言,好的模板引擎有简洁的语法规则、强大的功能、高效的渲染效率、详尽的帮助说明与不断的更新与维护。常见的前端模板引擎有:

Spring MVC 学习总结之FreeMarker模板引擎与动态页面静态化_第1张图片

常用的java后台模板引擎:jsp、FreeMarker、Velocity等。

Spring MVC 学习总结之FreeMarker模板引擎与动态页面静态化_第2张图片

请不要迷恋速度,为了推广的测试可能是片面的,好的模板引擎经得起时间考验,建议大家选择成熟的、常用的模板引擎。另外不管前后端的模板引擎原理都差不多,不外乎在模板中定义一些特别的标签后台正则匹配后替换,所以这里就以FreeMarker为例简介一下模板引擎的使用。另外我个人觉得ASP.NET MVC中使用的razor模板引擎非常好用,如果java有一款类似的就好了。

一、FreeMarker简介

FreeMarker是一款模板引擎,即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarkerTemplateLanguage(FTL)。它是简单的,专用的语言,不是像PHP那样成熟的编程语言。那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算,之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据,而在模板之外可以专注于要展示什么数据。

这种方式通常被称为MVC(模型视图控制器)模式,对于动态网页来说,是一种特别流行的模式。它帮助从开发人员(Java程序员)中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑,在没有程序员来修改或重新编译代码时,也可以修改页面的样式。

而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。

特征与亮点:

功能强大的模板语言:有条件的块,迭代,赋值,字符串和算术运算和格式化,宏和函数,编码等更多的功能;

多用途且轻量:零依赖,输出任何格式,可以从任何地方加载模板(可插拔),配置选项丰富;

智能的国际化和本地化:对区域设置和日期/时间格式敏感。

XML处理功能:将dom-s放入到XML数据模型并遍历它们,甚至处理他们的声明

通用的数据模型:通过可插拔适配器将java对象暴露于模板作为变量树。

FreeMarker是免费的,基于Apache许可证2.0版本发布。

获得FreeMarker

官网:http://freemarker.org/

中文帮助文档:https://sourceforge.net/projects/freemarker/files/chinese-manual/

下载FreeMarker jar包:下载地址http://freemarker.org/freemarkerdownload.html

中文网:http://freemarker.foofun.cn/

使用Maven依赖jar包:

复制代码
<dependency>
  <groupId>org.freemarkergroupId>
  <artifactId>freemarker-gaeartifactId>
  <version>2.3.25-incubatingversion>
dependency>
复制代码

FreeMarker用途

生成HTML Web页面,如作为MVC框架的视图

动态页面静态化等

代码生成器

二、第一个FreeMark示例

模板 + 数据模型 = 输出,FreeMarker基于设计者和程序员是具有不同专业技能的不同个体的观念,他们是分工劳动的:设计者专注于表示——创建HTML文件、图片、Web页面的其它可视化方面;程序员创建系统,生成设计页面要显示的数据。总之实现了数据与表现的分离。

2.1、新建一个Maven项目

新建一个简单Maven项目,不要选择内置模板,设置jdk版本为1.7。

2.2、添加依赖

修改pom.xml配置文件,增加freemark、junit依赖,修改后的pom.xml文件如下:

复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.zhangguogroupId>
    <artifactId>FreeMarkerDemoartifactId>
    <version>0.0.1version>
    <dependencies>
        <dependency>
            <groupId>org.freemarkergroupId>
            <artifactId>freemarkerartifactId>
            <version>2.3.23version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.10version>
        dependency>
    dependencies>
project>
复制代码

2.3、添加存放模板的文件夹

在src/main/java的包下添加一个名为“templates”目录(包),用于存放所有的freemarker模板。

 2.4、添加模板

在src/main/java/templates目录下添加名为“product.ftl”的FreeMarker模板,模板的内容如下:

复制代码
----------产品详细----------
产品名称:${name}
产品价格:${price}
设计作者:<#list users as user> ${user} 
------------------------------
复制代码

模板中一般分为不可变部分与可变部分,如“产品名称:”这些常量内容就是不可以变化的,而${}与<#>这些内容是可以根据数据动态变化的。

2.5、解析模板

使用FreeMarker可以读取到模板内容,将数据与模板绑定并渲染出结果,很好的实现了表现与数据分离。新建一个测试类,代码如下:

复制代码
package com.zhangguo.freemarkerdemo;

import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;

public class Test {

    public static void main(String[] args) throws Exception {
        
        //创建一个freemarker.template.Configuration实例,它是存储 FreeMarker 应用级设置的核心部分
        //指定版本号
        Configuration cfg=new Configuration(Configuration.VERSION_2_3_22);
        //设置模板目录
        cfg.setDirectoryForTemplateLoading(new File("src/main/java/templates"));
        //设置默认编码格式
        cfg.setDefaultEncoding("UTF-8");
        
        //数据
        Map product = new HashMap<>();
        product.put("name", "Huwei P8");
        product.put("price", "3985.7");
        product.put("users", new String[]{"Tom","Jack","Rose"});
        
        //从设置的目录中获得模板
        Template temp = cfg.getTemplate("product.ftl");
        
        //合并模板和数据模型
        Writer out = new OutputStreamWriter(System.out);
        temp.process(product, out);
        
        //关闭
        out.flush();
        out.close();
    }
}
复制代码

2.6、运行结果

三、动态页面静态化

动态页面静态化是指使用服务器后台技术将用户原来请求的动态页面变成静态内容缓存于服务器文件中,比如网站有一篇新闻名为由hot.jsp页面展示,默认情况下每当有客户端从服务器请求该新闻时服务器会解析hot.jsp页面渲染出静态内容响应给客户端,这样有一些问题,首先是每次请求都要解析服务器压力大,其次新闻的内容并没有真的存储在hot.jsp文件中而是存储在数据库里,对搜索引擎的爬虫不友好,不便SEO,另外访问动态的内容可能存在安全风险,如sql注入,XSS等网络攻击。解决办法是将hot.jsp页面静态化成一个叫hot.html的文件,服务器不再执行动态内容直接把静态页面响应给客户端,因为是纯静态的服务器压力会减轻,不担心网络安全问题;文章的内容直接存储在html文件中,对SEO友好。

3.1、动态页面静态化的优点

a) 利于搜索引擎优化(SEO)

b) 减轻服务器压力

c) 提高了网站的安全性

d) 加快了客户端的访问速度

3.2、动态页面静态化的问题

a) 页面过期与内容更新问题

如果一个页面的内容需要经常更新,就会要不断的生成新的静态页面,不是所有的页面都适合静态化。

b) 页面生成的问题

什么时候生成静态页面合适,有客户端第一次请求生成的,有定时生成的,也有后台管理时批量生成的。

c) 页面中部分内容是静态的,部分内容是动态的,如一篇文章的评论,访问次数,这些肯定不能静态。我暂时想到的办法是ajax和内嵌框架(iframe)

3.3、实现动态页面静态化

实现动态页面静态化的办法多种多样,这里使用FreeMarker,仅仅提供思路,代码没有封装与优化。

3.3.1、新建一个基于Maven的Web项目

 

3.3.2、添加依赖

这里没有使用MVC,只需依赖FreeMarker、Servlet与JSP核心包就可以了,修改后的pom.xml文件如下。

复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.zhangguogroupId>
    <artifactId>SpringMVC71artifactId>
    <version>0.0.1-SNAPSHOTversion>
    <packaging>warpackaging>
    <dependencies>
        
        <dependency>
            <groupId>org.freemarkergroupId>
            <artifactId>freemarker-gaeartifactId>
            <version>2.3.25-incubatingversion>
        dependency>
        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>3.0.1version>
            <scope>providedscope>
        dependency>
        
        <dependency>
            <groupId>javax.servlet.jspgroupId>
            <artifactId>jsp-apiartifactId>
            <version>2.1version>
            <scope>providedscope>
        dependency>
    dependencies>
project>
复制代码

依赖成功的结果:

3.3.3、创建文章POJO类

在src/main/java源代码目录下创建Article.java文件,该类代表文章,代码如下:

复制代码
package com.zhangguo.springmvc71.entities;

/**
 * 文章
 *
 */
public class Article {
    /*
     * 编号
     */
    private int id;
    /*
     * 标题
     */
    private String title;
    /*
     * 内容
     */
    private String content;

    public Article() {
    }

    public Article(int id, String title, String content) {
        super();
        this.id = id;
        this.title = title;
        this.content = content;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";
    }
}
复制代码

3.3.4、创建文章业务类

在src/main/java源代码目录下创建ArticleService.java文件,该类代表文章业务,主要提供文章数据,定义了一个文章集合中,初始化时向集合中随意添加了5个文章对象,代码如下:

复制代码
package com.zhangguo.springmvc71.Services;

import java.util.ArrayList;
import java.util.List;
import com.zhangguo.springmvc71.entities.Article;

/**
 * 文章业务类(模拟)
 *
 */
public class ArticleService {
    private static List
articles; static { articles = new ArrayList
(); articles.add(new Article(20160701, "不明真相的美国人被UFO惊呆了 其实是长征7号","据美国《洛杉矶时报》报道,当地时间周三晚(北京时间周四),在美国中西部的犹他州、内华达州、加利福利亚州,数千人被划过夜空的神秘火球吓到")); articles.add(new Article(20160702, "法国巴黎圣母院为教堂恐袭案遇害神父举行大弥撒", "而据美国战略司令部证实,其实这是中国长征七号火箭重新进入大气层,刚好经过加利福利亚附近。")); articles.add(new Article(20160703, "日东京知事候选人小池百合子回击石原:浓妆可以", "然而昨晚的美国人民可不明真相,有些人甚至怀疑这些火球是飞机解体,还有些人猜测是流星雨。")); articles.add(new Article(20160704, "日资慰安妇基金在首尔成立 韩国示威者闯入抗议","美国战略司令部发言人表示,到目前为止还没有任何受损报告,他说类似物体通常在大气中就会消失,这也解释了为何出现一道道光痕,这一切都并未造成什么威胁。")); articles.add(new Article(20160705, "中日关系正处十字路口日应寻求减少与华冲突","中国长征七号火箭6月25日在海南文昌航天发射中心首次发射,并成功升空进入轨道。有学者指出长征七号第二级火箭一直在地球低轨运行,一个月后重新进入大气层。")); } /** * 所有的文章 */ public List
getArticles() { return articles; } /* * 获得文章通过文章编号 */ public Article getArticle(int id) { for (Article article : articles) { if (article.getId() == id) { return article; } } return null; } }
复制代码

3.3.5、添加模板

在src/main/java源代码目录的templates包下添加两个模板,一个名为newsList.ftl用于生成新闻列表,另一个名为news.ftl用于生成单篇新闻,newsList.ftl文件内容如下:

复制代码
DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>新闻焦点title>
head>
<body>
    <div id="container">
    <h2>新闻焦点h2>
    <#setting number_format="#">
    <ul>
        <#list articles as article>
        <li>
            <a href="news/${article.id}.html">${article.title}a>
        li>
        #list>
    ul>
    div>
    <style>
       #container{
          font-family:"microsoft yahei";
          width:800px;
          margin:0 auto;
       }
       a{
         color:#333;
         text-decoration:none;
       }
       li{
         height:26px;
         line-height:26px;
       }
    style>
body>
html>
复制代码

文件中使用了FreeMarker标记,具体语法可以看第四点;news.ftl文件内容如下:

复制代码
DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${article.title}title>
head>
<body>
    <div id="container">
    <h2>${article.title}h2>
    <p>
         ${article.content}
    p>
    div>
    <style>
       #container{
          font-family:"microsoft yahei";
          width:800px;
          margin:0 auto;
       }
    style>
body>
html>
复制代码

3.3.6、添加Servlet生成静态页

新增一个名为News的Servlet类,当Servlet收到客户端请求时会查看系统中是否存在index.html(新闻列表)静态页面,如果存在直接转发,如果不存在则生成新闻列表静态页面及子页面。创建好的Servlet代码如下所示:

复制代码
package com.zhangguo.springmvc71.actions;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zhangguo.springmvc71.Services.ArticleService;
import com.zhangguo.springmvc71.entities.Article;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 *新闻列表
 */
@WebServlet("/News")
public class News extends HttpServlet {
    private static final long serialVersionUID = 1L;
    
    ArticleService articleService=new ArticleService();
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
        //设置编码格式与MIME类型
        response.setContentType("text/html; charset=UTF-8");
        
        //首页新闻列表路径
        String indexPath=request.getServletContext().getRealPath("/index.html");
        
        //文件是否存在
        File file=new File(indexPath);
        if(!file.exists()){
            //如果新闻列表不存在,生成新闻列表
            
            //创建一个freemarker.template.Configuration实例,它是存储 FreeMarker 应用级设置的核心部分
            //指定版本号
            Configuration cfg=new Configuration(Configuration.VERSION_2_3_22);
            //获得模板文件路径
            String templatePath=this.getClass().getClassLoader().getResource("/templates").getPath();
            //设置模板目录
            cfg.setDirectoryForTemplateLoading(new File(templatePath));
            //设置默认编码格式
            cfg.setDefaultEncoding("UTF-8");
            
            //数据
            Map articleData = new HashMap<>();
            List
articles=articleService.getArticles(); articleData.put("articles", articles); //从设置的目录中获得模板 Template template = cfg.getTemplate("newsList.ftl"); //合并模板和数据模型 try { //将数据与模板渲染的结果写入文件中 Writer writer=new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); template.process(articleData, writer); writer.flush(); articleData.clear(); template = cfg.getTemplate("news.ftl"); //生成单个新闻文件 for (Article article : articles) { articleData.put("article", article); //单个新闻文件 file=new File(request.getServletContext().getRealPath("/news/"+article.getId()+".html")); //文件输出流写入器 writer=new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); //将模板+数据生成的结果写入文件中,得到一个静态文件 template.process(articleData, writer); writer.flush(); } writer.close(); } catch (TemplateException e) { e.printStackTrace(); } } //如果新闻单页下存在,生成新闻单页 request.getRequestDispatcher("index.html").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
复制代码

从代码中可以看出生成的单篇文章全部存放在news目录下,要记得在webapp根目录下创建news目录。这里只是示例代码,如果要在项目中应用,应该把FreeMarker,文件操作的内容分Servlet分开。另外web.xml文件中添加index.html为第1个欢迎页,这样做的目的是当首页被生成时直接让服务器响应index.html。web.xml文件如下:

复制代码
xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <welcome-file-list>
        <welcome-file>index.htmlwelcome-file>
        <welcome-file>index.jspwelcome-file>
    welcome-file-list>
web-app>
复制代码

index.jsp直接转发到News Servlet中,文件内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<jsp:forward page="News">jsp:forward>

3.3.7、运行结果

3.3.8、小结

再次强调这只是一个示例;另外你可能会想到FreeMarker在这里的作用感觉不大,如果我们使用一些特别的标记嵌套在静态的页面中,然后后台替换其实同样可以做到,确实这样也可以,但对于复杂的内容FreeMarker替换的方式要更加优雅,效率要更高,如果你使用jsp作为模板效果也是一样的,只是他们的侧重点不一样而已,有点想念razor了。

四、FreeMarker模板语法

要编写复杂的模板需要熟悉FreeMarker语法规则,官网有详细说明,中文帮助也比较详细了,下面这些内容是从网上收罗来的,感谢网友的分享,经过整理与修改的内容如下。建议直接看官网的文档。

4.0、模板文件的4个组成部分

FreeMarker模板文件主要由如下4个部分组成:

1,文本:直接输出的部分

2,注释:<#-- ... -->格式部分,不会输出

3,插值:即${...}或#{...}格式的部分,将使用数据模型中的部分替代输出

4,FTL指令:FreeMarker指定,和HTML标记类似,名字前加#予以区分,不会输出

下面是一个FreeMarker模板的例子,包含了以上所说的4个部分

复制代码
<html>
<head>
<title>Welcome!title>
head>
<body>
<#--下面是文本将直接输出-->
Hello FreeMarker
<#-- 注释部分 -->
<#-- 下面使用插值 -->
<h1>Welcome ${user} !h1>
<u1>
<#-- 使用FTL指令 -->
<#list animals as being>
   <li>${being.name} for ${being.price} Euros
<#list>
<u1>
body>
html>
复制代码

4.1、FTL指令规则

在FreeMarker中,使用FTL标签来使用指令,FreeMarker有3种FTL标签,这和HTML标签是完全类似的.
1.开始标签:<#指令名 参数> 如<#list users as user>
2.结束标签: 如
3.单标签:<#指令名 参数/>

实际上,使用标签时前面的符号#也可能变成@,如果该指令是一个用户指令而不是系统内建指令时,应将#符号改成@符号.
使用FTL标签时,应该有正确的嵌套,而不是交叉使用,这和XML标签的用法完全一样.如果全用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息.FreeMarker会忽略FTL标签中的空白字符.值得注意的是< , /> 和指令之间不允许有空白字符.

4.2、 插值规则

FreeMarker的插值有如下两种类型:

1、通用插值${expr};

2、数字格式化插值:#{expr}或#{expr;format}

可以简单理解为输出表达式

4.2.1 通用插值

对于通用插值,又可以分为以下4种情况:

1、插值结果为字符串值:直接输出表达式结果

2、插值结果为数字值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子:

<#setting number_format="currency"/> <#-- 设置数字格式为货币 -->

<#assign answer=42/>  <#-- 赋值 -->

${answer} <#-- 输出 -->

${answer?string} <#-- 输出格式为字符类型,与上面相同-->

${answer?string.number} <#-- 输出格式为数字类型-->

${answer?string.currency} <#-- 输出格式为货币类型-->

${answer?string.percent} <#-- 输出格式为百分比类型-->

输出结果是:

$42.00

$42.00

42

$42.00

4,200%

3,插值结果为日期值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子:

${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")}

${lastUpdated?string("EEE, MMM d, ''yy")}

${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")}

输出结果是:

2008-04-08 08:08:08 Pacific Daylight Time

Tue, Apr 8, '03

Tuesday, April 08, 2003, 08:08:08 PM (PDT)

4,插值结果为布尔值:根据默认格式(由#setting指令设置)将表达式结果转换成文本输出.可以使用内建的字符串函数格式化单个插值,如下面的例子:

<#assign foo=true/>
${foo?string("yes", "no")}
输出结果是:
yes

4.2.2 数字格式化插值

数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是:
mX:小数部分最小X位
MX:小数部分最大X位
如下面的例子:
<#assign x=2.582/>
<#assign y=4/>
#{x; M2}
#{y; M2}
#{x; m2}
#{y; m2}
#{x; m1M2}
#{x; m1M2} 

输出结果:

2.58
4
2.58
4.00
2.58
2.58

4.3、表达式

表达式是FreeMarker模板的核心功能,表达式放置在插值语法${}之中时,表明需要输出表达式的值;表达式语法也可与FreeMarker标签结合,用于控制输出.实际上FreeMarker的表达式功能非常强大,它不仅支持直接指定值,输出变量值,也支持字符串格式化输出和集合访问等功能.

4.3.1、直接指定值

使用直接指定值语法让FreeMarker直接输出插值中的值,而不是输出变量值.直接指定值可以是字符串,数值,布尔值,集合和MAP对象.

1,字符串
直接指定字符串值使用单引号或双引号限定,如果字符串值中包含特殊字符需要转义,看下面的例子:
   

{'我名字是\"annlee\"'}
输出结果是: 
我的文件保存在C:\盘
我名字是"annlee"

FreeMarker支持如下转义字符:
\";双引号(u0022)
\';单引号(u0027)
\\;反斜杠(u005C)
\n;换行(u000A)
\r;回车(u000D)
\t;Tab(u0009)
\b;退格键(u0008)
\f;Form feed(u000C)
\l;<
\g;>
\a;&
\{;{
\xCode;直接通过4位的16进制数来指定Unicode码,输出该unicode码对应的字符.

如果某段文本中包含大量的特殊符号,FreeMarker提供了另一种特殊格式:可以在指定字符串内容的引号前增加r标记,在r标记后的文件将会直接输出.看如下代码:
 

{r"C:\foo\bar"}
输出结果是:
${foo}
C:\foo\bar

2、数值
表达式中的数值直接输出,不需要引号.小数点使用"."分隔,不能使用分组","符号.FreeMarker目前还不支持科学计数法,所以"1E3"是错误的.在FreeMarker表达式中使用数值需要注意以下几点:
1、数值不能省略小数点前面的0,所以".5"是错误的写法
2、数值8 , +8 , 8.00都是相同的

3、布尔值
直接使用true和false,不使用引号.

4、集合
集合以方括号包括,各集合元素之间以英文逗号","分隔,看如下的例子:
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as week>
${week}

输出结果是:
星期一
星期二
星期三
星期四
星期五
星期六
星期天

除此之外,集合元素也可以是表达式,例子如下:
[2 + 2, [1, 2, 3, 4], "whatnot"]

还可以使用数字范围定义数字集合,如2..5等同于[2, 3, 4, 5],但是更有效率.注意,使用数字范围来定义集合时无需使用方括号,数字范围也支持反递增的数字范围,如5..2

5,Map对象
Map对象使用花括号包括,Map中的key-value对之间以英文冒号":"分隔,多组key-value对之间以英文逗号","分隔.下面是一个例子:
{"语文":78, "数学":80}
Map对象的key和value都是表达式,但是key必须是字符串

4.3.2、输出变量值

FreeMarker的表达式输出变量时,这些变量可以是顶层变量,也可以是Map对象中的变量,还可以是集合中的变量,并可以使用点(.)语法来访问Java对象的属性.下面分别讨论这些情况

1、顶层变量
所谓顶层变量就是直接放在数据模型中的值,例如有如下数据模型:
Map root = new HashMap();   //创建数据模型
root.put("name","annlee");   //name是一个顶层变量

对于顶层变量,直接使用线 

,@和#的组合,且不能以数字开头号.为了输出上面的name的值,可以使用如下语法:
${name}

2、输出集合元素
如果需要输出集合元素,则可以根据集合元素的索引来输出集合元素,集合元素的索引以方括号指定.假设有索引:
["星期一","星期二","星期三","星期四","星期五","星期六","星期天"].该索引名为week,如果需要输出星期三,则可以使用如下语法:
${week[2]}   //输出第三个集合元素

此外,FreeMarker还支持返回集合的子集合,如果需要返回集合的子集合,则可以使用如下语法:
week[3..5]   //返回week集合的子集合,子集合中的元素是week集合中的第4-6个元素

3、输出Map元素
这里的Map对象可以是直接HashMap的实例,甚至包括JavaBean实例,对于JavaBean实例而言,我们一样可以把其当成属性为key,属性值为value的Map实例.为了输出Map元素的值,可以使用点语法或方括号语法.假如有下面的数据模型:
Map root = new HashMap();
Book book = new Book();
Author author = new Author();
author.setName("annlee");
author.setAddress("gz");
book.setName("struts2");
book.setAuthor(author);
root.put("info","struts");
root.put("book", book);

为了访问数据模型中名为struts2的书的作者的名字,可以使用如下语法:
book.author.name    //全部使用点语法
book["author"].name
book.author["name"]    //混合使用点语法和方括号语法
book["author"]["name"]   //全部使用方括号语法

使用点语法时,变量名字有顶层变量一样的限制,但方括号语法没有该限制,因为名字可以是任意表达式的结果.

4.3.3、字符串操作

FreeMarker的表达式对字符串操作非常灵活,可以将字符串常量和变量连接起来,也可以返回字符串的子串等.

字符串连接有两种语法:
1、使用${..}或#{..}在字符串常量部分插入表达式的值,从而完成字符串连接.
2、直接使用连接运算符+来连接字符串

例如有如下数据模型:
Map root = new HashMap();

root.put("user","annlee");
下面将user变量和常量连接起来:
使 

{"hello, " + user + "!"} //使用+号来连接
上面的输出字符串都是hello,annlee!,可以看出这两种语法的效果完全一样.

值得注意的是,{..}只能用于文本部分,不能用于表达式,下面的代码是错误的: <#if

{isBig}>Wow!
<#if "${isBig}">Wow!
应该写成:<#if isBig>Wow!

截取子串可以根据字符串的索引来进行,截取子串时如果只指定了一个索引值,则用于取得字符串中指定索引所对应的字符;如果指定两个索引值,则返回两个索引中间的字符串子串.假如有如下数据模型:
Map root = new HashMap();

root.put("book","struts2,freemarker");
可以通过如下语法来截取子串:
 

{book[4]}   //结果是st
${book[1..4]}     //结果是trut

4.3.4、集合连接运算符

这里所说的集合运算符是将两个集合连接成一个新的集合,连接集合的运算符是+,看如下的例子:
<#list ["星期一","星期二","星期三"] + ["星期四","星期五","星期六","星期天"] as week>
${week}

输出结果是:星期一 星期二 星期三 星期四 星期五 星期六 星期天

4.3.5、Map连接运算符

Map对象的连接运算符也是将两个Map对象连接成一个新的Map对象,Map对象的连接运算符是+,如果两个Map对象具有相同的key,则右边的值替代左边的值.看如下的例子:
<#assign scores = {"语文":86,"数学":78} + {"数学":87,"Java":93}>
语文成绩是 

{scores.数学}
Java成绩是${scores.Java}

输出结果是:

语文成绩是86
数学成绩是87
Java成绩是93

4.3.6、算术运算符

FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , % 看如下的代码:
<#assign x=5>
 

{ x /2 }
${ 12 %10 }
输出结果是:

-75
2.5
2

在表达式中使用算术运算符时要注意以下几点:
1、运算符两边的运算数字必须是数字
2、使用+运算符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串再连接,如:${3 + "5"},结果是:35

使用内建的int函数可对数值取整,如:
<#assign x=5>
 

{ 1.1?int }
 

{ -1.1?int }
${ -1.999?int }
结果是:

2
1
1
-1
-1

4.3.7、比较运算符

表达式中支持的比较运算符有如下几个:
1,=或者==:判断两个值是否相等.
2,!=:判断两个值是否不等.
3,>或者gt:判断左边值是否大于右边值
4,>=或者gte:判断左边值是否大于等于右边值
5,<或者lt:判断左边值是否小于右边值
6,<=或者lte:判断左边值是否小于等于右边值

注意:=和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>

4.3.8、逻辑运算符

逻辑运算符有如下几个:
逻辑与:&&
逻辑或:||
逻辑非:!
逻辑运算符只能作用于布尔值,否则将产生错误

4.3.9、内建函数

FreeMarker还提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来轮换输出变量.下面是常用的内建的字符串函数:
html:对字符串进行HTML编码
cap_first:使字符串第一个字母大写
lower_case:将字符串转换成小写
upper_case:将字符串转换成大写
trim:去掉字符串前后的空白字符

下面是集合的常用内建函数
size:获取序列中元素的个数

下面是数字值的常用内建函数
int:取得数字的整数部分,结果带符号

例如:
<#assign test="Tom & Jerry">
 

{test?upper_case?html}
结果是:

Tom & Jerry
TOM & JERRY

4.3.10、空值处理运算符

FreeMarker对空值的处理非常严格,FreeMarker的变量必须有值,没有被赋值的变量就会抛出异常,因为FreeMarker未赋值的变量强制出错可以杜绝很多潜在的错误,如缺失潜在的变量命名,或者其他变量错误.这里所说的空值,实际上也包括那些并不存在的变量,对于一个Java的null值而言,我们认为这个变量是存在的,只是它的值为null,但对于FreeMarker模板而言,它无法理解null值,null值和不存在的变量完全相同.

为了处理缺失变量,FreeMarker提供了两个运算符:
!:指定缺失变量的默认值
??:判断某个变量是否存在

其中,!运算符的用法有如下两种:
variable!或variable!defaultValue,第一种用法不给缺失的变量指定默认值,表明默认值是空字符串,长度为0的集合,或者长度为0的Map对象.

使用!指定默认值时,并不要求默认值的类型和变量类型相同.使用??运算符非常简单,它总是返回一个布尔值,用法为:variable??,如果该变量存在,返回true,否则返回false

示例:

${tom!"tom is missed"}
<#if !jack??>jack is missed

输出:

tom is missed
jack is missed

4.3.11、运算符的优先级

FreeMarker中的运算符优先级如下(由高到低排列):
1,一元运算符:!
2,内建函数:?
3,乘除法:*, / , %
4,加减法:- , +
5,比较:> , < , >= , <= (lt , lte , gt , gte)
6,相等:== , = , !=
7,逻辑与:&&
8,逻辑或:||
9,数字范围:..

实际上,我们在开发过程中应该使用括号来严格区分,这样的可读性好,出错少

4.4、FreeMarker的常用指令

FreeMarker的FTL指令也是模板的重要组成部分,这些指令可实现对数据模型所包含数据的抚今迭代,分支控制.除此之外,还有一些重要的功能,也是通过FTL指令来实现的.

4.4.1、if指令

这是一个典型的分支控制指令,该指令的作用完全类似于Java语言中的if,if指令的语法格式如下:
<#if condition>...
<#elseif condition>...
<#elseif condition>...
<#else> ...

例子如下:
<#assign age=23>
<#if (age>60)>老年人
<#elseif (age>40)>中年人
<#elseif (age>20)>青年人
<#else> 少年人

输出结果是:青年人
上面的代码中的逻辑表达式用括号括起来主要是因为里面有>符号,由于FreeMarker会将>符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号.

4.4.2、switch , case , default , break指令

这些指令显然是分支指令,作用类似于Java的switch语句,switch指令的语法结构如下:
<#switch value>
<#case refValue>...<#break>
<#case refValue>...<#break>
<#default>...

示例:

<#assign level=1>
<#switch level>
<#case 1>A级<#break>
<#case 2>B级<#break>
<#case 3>C级<#break>
<#default>未知级别

输出:

A级

4.4.3、list, break指令

list指令是一个迭代输出指令,用于迭代输出数据模型中的集合,list指令的语法格式如下:
<#list sequence as item>
...

上面的语法格式中,sequence就是一个集合对象,也可以是一个表达式,但该表达式将返回一个集合对象,而item是一个任意的名字,就是被迭代输出的集合元素.此外,迭代集合对象时,还包含两个特殊的循环变量:
item_index:当前变量的索引值
item_has_next:是否存在下一个对象
也可以使用<#break>指令跳出迭代

示例:

<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as week>
   

{week}<#if week_has_next>,
<#if week="星期四"><#break>

输出结果:

1.星期一,
2.星期二,
3.星期三,
4.星期四,

4.4.4、include指令

include指令的作用类似于JSP的包含指令,用于包含指定页.include指令的语法格式如下:
<#include filename [options]>
在上面的语法格式中,两个参数的解释如下:
filename:该参数指定被包含的模板文件
options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,其中encoding指定包含页面时所用的解码集,而parse指定被包含文件是否作为FTL文件来解析,如果省略了parse选项值,则该选项默认是true.

4.4.5、import指令

该指令用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map对象中,import指令的语法格式如下:
<#import "/lib/common.ftl" as com>
上面的代码将导入/lib/common.ftl模板文件中的所有变量,交将这些变量放置在一个名为com的Map对象中.

4.4.6、noparse指令

noparse指令指定FreeMarker不处理该指定里包含的内容,该指令的语法格式如下:
<#noparse>...

看如下的例子:
<#noparse>
<#list books as book>
    

{book.author}


输出如下:
<#list books as book>
    

{book.author}

4.4.7、escape , noescape指令

escape指令导致body区的插值都会被自动加上escape表达式,但不会影响字符串内的插值,只会影响到body内出现的插值,使用escape指令的语法格式如下:
<#escape identifier as expression>...
<#noescape>...

看如下的代码:
<#escape x as x?html>
First name: 

{lastName}
Maiden name: {maidenName}  上面的代码等同于: First name:{firstName?html}
Last name:  

{maidenName?html}

escape指令在解析模板时起作用而不是在运行时起作用,除此之外,escape指令也嵌套使用,子escape继承父escape的规则,如下例子:
<#escape x as x?html>
Customer Name:{customerName} Items to ship; <#escape x as itemCodeToNameMap[x]>

{itemCode1}
    {itemCode3}
   {itemCode4}   上面的代码类似于: Customer Name:{customerName?html}
Items to ship;
 {itemCodeToNameMap[itemCode2]?html}
 

{itemCodeToNameMap[itemCode4]?html}

对于放在escape指令中所有的插值而言,这此插值将被自动加上escape表达式,如果需要指定escape指令中某些插值无需添加escape表达式,则应该使用noescape指令,放在noescape指令中的插值将不会添加escape表达式.

4.4.8、assign指令

assign指令在前面已经使用了多次,它用于为该模板页面创建或替换一个顶层变量,assign指令的用法有多种,包含创建或替换一个顶层变量,或者创建或替换多个变量等,它的最简单的语法如下:<#assign name=value [in namespacehash]>,这个用法用于指定一个名为name的变量,该变量的值为value,此外,FreeMarker允许在使用assign指令里增加in子句,in子句用于将创建的name变量放入namespacehash命名空间中.

assign指令还有如下用法:<#assign name1=value1 name2=value2 ... nameN=valueN [in namespacehash]>,这个语法可以同时创建或替换多个顶层变量,此外,还有一种复杂的用法,如果需要创建或替换的变量值是一个复杂的表达式,则可以使用如下语法格式:<#assign name [in namespacehash]>capture this,在这个语法中,是指将assign指令的内容赋值给name变量.如下例子:
<#assign weeks>
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
{n}  

{weeks}
上面的代码将产生如下输出:星期一 星期二 星期三 星期四 星期五 星期六 星期天

虽然assign指定了这种复杂变量值的用法,但是我们也不要滥用这种用法,如下例子:<#assign x>Hello {user}!,以上代码改为如下写法更合适:<#assign x="Hello

{user}!">

4.4.9、setting指令

该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:<#setting name=value>,在这个格式中,name的取值范围包含如下几个:
locale:该选项指定该模板所用的国家/语言选项
number_format:指定格式化输出数字的格式
boolean_format:指定两个布尔值的语法格式,默认值是true,false
date_format,time_format,datetime_format:指定格式化输出日期的格式
time_zone:设置格式化输出日期时所使用的时区

4.4.10、macro , nested , return指令

macro可以用于实现自定义指令,通过使用自定义指令,可以将一段模板片段定义成一个用户指令,使用macro指令的语法格式如下:
<#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...

在上面的格式片段中,包含了如下几个部分:
name:name属性指定的是该自定义指令的名字,使用自定义指令时可以传入多个参数
paramX:该属性就是指定使用自定义指令时报参数,使用该自定义指令时,必须为这些参数传入值
nested指令:nested标签输出使用自定义指令时的中间部分
nested指令中的循环变量:这此循环变量将由macro定义部分指定,传给使用标签的模板
return指令:该指令可用于随时结束该自定义指令.

看如下的例子:
<#macro book>   //定义一个自定义指令
j2ee

<@book />    //使用刚才定义的指令
上面的代码输出结果为:j2ee

在上面的代码中,可能很难看出自定义标签的用处,因为我们定义的book指令所包含的内容非常简单,实际上,自定义标签可包含非常多的内容,从而可以实现更好的代码复用.此外,还可以在定义自定义指令时,为自定义指令指定参数,看如下代码:
<#macro book booklist>     //定义一个自定义指令booklist是参数
<#list booklist as book>
   ${book}


<@book booklist=["spring","j2ee"] />   //使用刚刚定义的指令
上面的代码为book指令传入了一个参数值,上面的代码的输出结果为:spring j2ee

不仅如此,还可以在自定义指令时使用nested指令来输出自定义指令的中间部分,看如下例子:
<#macro page title>


   FreeMarker示例页面 - <span class="MathJax"><span class="math" style="width:26.002em;"><span style="width:20.8em;height:0px;font-size:125%;"><span class="mrow"><span class="texatom"><span class="mrow"><span class="mi"><img src="http://img.e-com-net.com/image/info8/f27980ad1e244245814d0c58b1e00d0b.png" style="width:7px;height:11px;margin-right:.029em;" alt="" width="6" height="10"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/f31d8223214241b08aa43ce88c575890.png" style="width:6px;height:12px;margin-right:.041em;" alt="" width="5" height="11"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/f27980ad1e244245814d0c58b1e00d0b.png" style="width:7px;height:11px;margin-right:.029em;" alt="" width="6" height="10"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/8cd4ce894a8b4e4689a4deecf3af5cc1.png" style="width:6px;height:13px;margin-right:.03em;" alt="" width="5" height="12"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/b532503f7c53496195667b334850bf8b.png" style="width:9px;height:8px;margin-right:.035em;" alt="" width="8" height="7"></span><span class="mo"><img src="http://img.e-com-net.com/image/info8/cfa0b4488c54443383ce3f26bd81e997.png" style="width:8px;height:13px;margin-right:.053em;" alt="" width="7" height="12"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/0fded78197184fd88c7e42ac48afd377.png" style="width:11px;height:12px;margin-right:.02em;" alt="" width="10" height="11"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/f27980ad1e244245814d0c58b1e00d0b.png" style="width:7px;height:11px;margin-right:.029em;" alt="" width="6" height="10"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/b8f91c81e9df414ca65a1e651b273a6b.png" style="width:17px;height:8px;margin-right:.02em;" alt="" width="15" height="7"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/8cd4ce894a8b4e4689a4deecf3af5cc1.png" style="width:6px;height:13px;margin-right:.03em;" alt="" width="5" height="12"></span></span></span><span class="mo" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/90e7458e35fe488daea7025fe3362acd.png" style="width:13px;height:12px;margin-right:.079em;" alt="" width="12" height="11"></span><span class="texatom" style="padding-left:.278em;"><span class="mrow"><span class="mo"><img src="http://img.e-com-net.com/image/info8/1e3436fb11e644a59046de7e321a123a.png" style="width:9px;height:20px;vertical-align:-4px;margin-right:.052em;" alt="" width="0" height="0"></span></span></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/f27980ad1e244245814d0c58b1e00d0b.png" style="width:7px;height:11px;margin-right:.029em;" alt="" width="6" height="10"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/f31d8223214241b08aa43ce88c575890.png" style="width:6px;height:12px;margin-right:.041em;" alt="" width="5" height="11"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/f27980ad1e244245814d0c58b1e00d0b.png" style="width:7px;height:11px;margin-right:.029em;" alt="" width="6" height="10"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/8cd4ce894a8b4e4689a4deecf3af5cc1.png" style="width:6px;height:13px;margin-right:.03em;" alt="" width="5" height="12"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/b532503f7c53496195667b334850bf8b.png" style="width:9px;height:8px;margin-right:.035em;" alt="" width="8" height="7"></span><span class="mo" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/21d553d0b93c41ebb4249e0788a4a415.png" style="width:13px;height:12px;vertical-align:-1px;margin-right:.079em;" alt="" width="12" height="11"><img src="http://img.e-com-net.com/image/info8/90e7458e35fe488daea7025fe3362acd.png" style="width:13px;height:12px;margin-right:.079em;" alt="" width="12" height="11"></span><span class="texatom" style="padding-left:.278em;"><span class="mrow"><span class="mo"><img src="http://img.e-com-net.com/image/info8/1e3436fb11e644a59046de7e321a123a.png" style="width:9px;height:20px;vertical-align:-4px;margin-right:.052em;" alt="" width="0" height="0"></span></span></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/0fded78197184fd88c7e42ac48afd377.png" style="width:11px;height:12px;margin-right:.02em;" alt="" width="10" height="11"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/b532503f7c53496195667b334850bf8b.png" style="width:9px;height:8px;margin-right:.035em;" alt="" width="8" height="7"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/b41aaf60082346519b13c74224ee180e.png" style="width:10px;height:8px;margin-right:.022em;" alt="" width="9" height="7"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/5044c4e0629a490d813ab5998f76fd9f.png" style="width:10px;height:12px;margin-right:-.003em;" alt="" width="9" height="11"><span style="height:1px;width:.003em;"></span></span><span class="mo" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/21d553d0b93c41ebb4249e0788a4a415.png" style="width:13px;height:12px;vertical-align:-1px;margin-right:.079em;" alt="" width="12" height="11"><img src="http://img.e-com-net.com/image/info8/90e7458e35fe488daea7025fe3362acd.png" style="width:13px;height:12px;margin-right:.079em;" alt="" width="12" height="11"></span><span class="mi" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/a94ebf95c62242b68d99f4231e6dfb9b.png" style="width:8px;height:12px;margin-right:.007em;" alt="" width="7" height="11"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/79bd6177cecc4a2497546b925791759a.png" style="width:9px;height:8px;margin-right:.009em;" alt="" width="8" height="7"></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/5044c4e0629a490d813ab5998f76fd9f.png" style="width:10px;height:12px;margin-right:-.003em;" alt="" width="9" height="11"><span style="height:1px;width:.003em;"></span></span><span class="mi"><img src="http://img.e-com-net.com/image/info8/cdcc82b7c42e4d0bbbc1ed8879e80f8b.png" style="width:10px;height:11px;vertical-align:-3px;margin-right:-.006em;" alt="" width="9" height="10"><span style="height:1px;width:.006em;"></span></span><span class="mo" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/21d553d0b93c41ebb4249e0788a4a415.png" style="width:13px;height:12px;vertical-align:-1px;margin-right:.079em;" alt="" width="12" height="11"><img src="http://img.e-com-net.com/image/info8/90e7458e35fe488daea7025fe3362acd.png" style="width:13px;height:12px;margin-right:.079em;" alt="" width="12" height="11"></span><span class="mi" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/0fded78197184fd88c7e42ac48afd377.png" style="width:11px;height:12px;margin-right:.02em;" alt="" width="10" height="11"></span><span class="mn"><img src="http://img.e-com-net.com/image/info8/eed9cd29bedf4c718d7a8e1493222ae0.png" style="width:9px;height:13px;margin-right:.069em;" alt="" width="8" height="12"></span><span class="mo" style="padding-left:.278em;"><img src="http://img.e-com-net.com/image/info8/21d553d0b93c41ebb4249e0788a4a415.png" style="width:13px;height:12px;vertical-align:-1px;margin-right:.079em;" alt="" width="12" height="11"></span></span> <span style="width:0px;height:2.35em;"></span></span><span style="vertical-align:-.358em;border-left:0px solid;width:0px;height:1.306em;"></span></span></span></p> <p>{title?html}</h1><br>   <#nested>      //用于引入用户自定义指令的标签体<br></body><br></html><br></#macro><br>上面的代码将一个HTML页面模板定义成一个page指令,则可以在其他页面中如此page指令:<br><#import "/common.ftl" as com>     //假设上面的模板页面名为common.ftl,导入页面<br><@com.page title="book list"><br><u1><br><li>spring</li><br><li>j2ee</li><br></ul><br></@com.page></p> <p>从上面的例子可以看出,使用macro和nested指令可以非常容易地实现页面装饰效果,此外,还可以在使用nested指令时,指定一个或多个循环变量,看如下代码:<br><#macro book><br><#nested 1>      //使用book指令时指定了一个循环变量值<br><#nested 2><br></#macro><br><@book ;x> ${x} .图书</@book><br>当使用nested指令传入变量值时,在使用该自定义指令时,就需要使用一个占位符(如book指令后的;x).上面的代码输出文本如下:<br>1 .图书    2 .图书</p> <p>在nested指令中使用循环变量时,可以使用多个循环变量,看如下代码:</p> <p><#macro repeat count><br><#list 1..count as x> <br> <#nested x, x/2, x==count><br></#list><br></#macro></p> <p><@repeat count=4 ;c,halfc,last><br><span class="MathJax"><span class="math" style="width:.352em;"><span style="width:.25em;height:0px;font-size:125%;"><span class="mrow"><span class="texatom"><span class="mrow"><span class="mi"><img src="http://img.e-com-net.com/image/info8/903d8aab07a34ab7a56a442176c90cbf.png" style="width:9px;height:8px;margin-right:.004em;" alt="" width="8" height="7"></span></span></span><span class="mo"><img src="http://img.e-com-net.com/image/info8/db525c82c2e54a59a02738476bb50537.png" style="width:4px;height:3px;margin-right:.075em;" alt="" width="4" height="3"></span></span> <span style="width:0px;height:2.35em;"></span></span><span style="vertical-align:-.075em;border-left:0px solid;width:0px;height:.66em;"></span></span></span></p> <p>{halfc}<#if last> Last! </#if><br></@repeat></p> <p><br>输出结果:</p> <p>1. 0.5<br>2. 1<br>3. 1.5<br>4. 2 Last! </p> <p>return指令用于结束macro指令,一旦在macro指令中执行了return指令,则FreeMarker不会继续处理macro指令里的内容,看如下代码:<br><#macro book><br>spring<br><#return><br>j2ee<br></#macro><br><@book /><br>上面的代码输出:spring,而j2ee位于return指令之后,不会输出。</p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1697650678773657600"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(spring,mvc)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1773569717865349120.htm" title="SpringMVC设置全局异常处理器" target="_blank">SpringMVC设置全局异常处理器</a> <span class="text-muted">水岸齐天</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>文章目录背景分析使用@ControllerAdvice(@RestControllerAdvice)+@ExceptionHandler实现全局异常全局异常处理-多个处理器匹配顺序存在一个类中存在不同的类中对于过滤器和拦截器中的异常,有两种思路可以考虑背景在项目中我们有需求做一个全局异常处理,来规范所有出去的异常信息。参考:官方文档分析首先ControllerAdvice(RestControll</div> </li> <li><a href="/article/1773545803021877248.htm" title="使用多线程的方式模拟高并发请求接口,用于自测接口的稳定性【项目】" target="_blank">使用多线程的方式模拟高并发请求接口,用于自测接口的稳定性【项目】</a> <span class="text-muted">还算善良_</span> <a class="tag" taget="_blank" href="/search/%E7%A7%81%E6%9C%89%E4%BB%A3%E7%A0%81%E5%BA%93/1.htm">私有代码库</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E5%85%B7%E7%B1%BB/1.htm">工具类</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/list/1.htm">list</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a> <div>packagecom.gitee.taven.test;importcom.gitee.taven.ApiResult;importcom.gitee.taven.aop.RepeatSubmitAspect;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.an</div> </li> <li><a href="/article/1773528182234873856.htm" title="springboot集成logback-spring.xml文件" target="_blank">springboot集成logback-spring.xml文件</a> <span class="text-muted">RT_0114</span> <a class="tag" taget="_blank" href="/search/SpringBoot/1.htm">SpringBoot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/logback/1.htm">logback</a> <div>彩色日志日志分debug和error文件输出,方便开发人员运维日志限制最大保管天数日志限制总量大小占用量GB日志限制单个文件大小MB日志显示最大保留天数屏蔽没用的日志${CONSOLE_LOG_PATTERN}${log.path}/debug.log${log.path}/%d{yyyy-MM-dd,aux}/debug.%d{yyyy-MM-dd}.%i.log.gz1024MB50GB365</div> </li> <li><a href="/article/1773465614472511488.htm" title="eclipse导入项目 warning报错 org.springframework.ide.eclipse.core.springnature" target="_blank">eclipse导入项目 warning报错 org.springframework.ide.eclipse.core.springnature</a> <span class="text-muted">zhangfeng1133</span> <a class="tag" taget="_blank" href="/search/ide/1.htm">ide</a><a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>报错org.springframework.ide.eclipse.core.springnature报错信息"org.springframework.ide.eclipse.core.springnature"通常表示EclipseIDE中与Spring框架集成的插件出现了问题。这个错误可能是因为SpringIDE插件没有正确安装或配置,或者Eclipse的更新过程中出现了问题。解决方法:确认S</div> </li> <li><a href="/article/1773413750980804608.htm" title="linux安装docker及docker-compose 部署spring boot项目" target="_blank">linux安装docker及docker-compose 部署spring boot项目</a> <span class="text-muted">时而有事儿</span> <a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>linux系统环境:centos5.14本篇描述的是在centos系统版本下安装docker,如果是ubuntu版本,请看这篇文章:linuxubuntu20安装docker和docker-compose-CSDN博客正文:安装docker和docker-compose安装docker---------运行命名等待安装完成遇到选择直接输入yyuminstall-yyum-utilsdevice-m</div> </li> <li><a href="/article/1773347920293199872.htm" title="Vue 常见面试题(一)" target="_blank">Vue 常见面试题(一)</a> <span class="text-muted">安生生申</span> <a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">面试题</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>目录1、Vue的最大的优势是什么?(必会)2、Vue和jQuery两者之间的区别是什么?(必会)3、MVVM和MVC区别是什么?哪些场景适合?(必会)1、基本定义2、使用场景3、两者之间的区别4、Vue数据双向绑定的原理是什么?(必会)5、Object.defineProperty和Proxy的区别(必会)6、Vue生命周期总共分为几个阶段?(必会)7、第一次加载页面会触发哪几个钩子函数?(必会)</div> </li> <li><a href="/article/1772673815097180160.htm" title="Websocket服务监听收发消息" target="_blank">Websocket服务监听收发消息</a> <span class="text-muted">beiback</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%97%AE%E9%A2%98/1.htm">服务器问题</a><a class="tag" taget="_blank" href="/search/websocket/1.htm">websocket</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/1.htm">网络协议</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a> <div>目录1.pom依赖坐标2.项目配置端口和项目包名2.创建处理器3.注册处理器4.前端页面1.pom依赖坐标org.springframework.bootspring-boot-starter-websocket2.项目配置端口和项目包名application.propertiesserver.port=8088//路径规范:为应用的所有servlet提供一个统一的前缀,使URL结构更加清晰和一致</div> </li> <li><a href="/article/1772654174425645056.htm" title="基于SSM+Vue企业销售培训系统 企业人才培训系统 企业课程培训管理系统 企业文化培训班系统Java" target="_blank">基于SSM+Vue企业销售培训系统 企业人才培训系统 企业课程培训管理系统 企业文化培训班系统Java</a> <span class="text-muted">计算机程序老哥</span> <div>作者主页:计算机毕业设计老哥有问题可以主页问我一、开发介绍1.1开发环境开发语言:Java数据库:MySQL系统架构:B/S后端:SSM(Spring+SpringMVC+Mybatis)前端:Vue工具:IDEA或者Eclipse,JDK1.8,Maven二、系统介绍2.1图片展示注册登录页面:登陆.png前端页面功能:首页、培训班、在线学习、企业文化、交流论坛、试卷列表、系统公告、留言反馈、个</div> </li> <li><a href="/article/1772556247065755648.htm" title="使用Spring Boot Admin监控和管理Spring Boot应用程序" target="_blank">使用Spring Boot Admin监控和管理Spring Boot应用程序</a> <span class="text-muted">岚珂瓜呱</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a> <div>使用SpringBootAdmin监控和管理SpringBoot应用程序SpringBootAdmin是一个用于监控和管理SpringBoot应用程序的开源工具。它提供了一个直观的用户界面,用于查看应用程序的健康状态、详细信息、日志等,并支持一些管理功能。下面是一个简单的示例,演示如何在SpringBoot应用程序中集成SpringBootAdmin:添加SpringBootAdmin依赖:首先,</div> </li> <li><a href="/article/1772495822802452480.htm" title="使用Spring Security进行LDAP(轻量目录访问协议)认证" target="_blank">使用Spring Security进行LDAP(轻量目录访问协议)认证</a> <span class="text-muted">岚珂瓜呱</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>使用SpringSecurity进行LDAP(轻量目录访问协议)认证使用SpringSecurity进行LDAP认证非常简单,您只需配置SpringSecurity以连接到LDAP服务器并执行认证即可。以下是一个简单的示例,演示如何在SpringBoot应用程序中实现LDAP认证:添加SpringSecurity和SpringLDAP依赖:首先,您需要添加SpringSecurity和Spring</div> </li> <li><a href="/article/1772253016796233728.htm" title="论文整理:隐私签名" target="_blank">论文整理:隐私签名</a> <span class="text-muted">yixvxi</span> <a class="tag" taget="_blank" href="/search/Survey/1.htm">Survey</a><a class="tag" taget="_blank" href="/search/%E6%96%87%E6%A1%A3%E8%B5%84%E6%96%99/1.htm">文档资料</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a> <div>最近准备开题了(苦恼…),整理一些看过/没看过的论文。持续更新…数字签名:隐私数字签名的定义&安全性(book)0.Deffie-Hellman.NewDirectionsinCryptography.1976Katz,J.(2010).DigitalSignatures:BackgroundandDefinitions.In:DigitalSignatures.Springer,Boston,M</div> </li> <li><a href="/article/1772220423782596608.htm" title="配置 IDEA 远程连接应用服务器" target="_blank">配置 IDEA 远程连接应用服务器</a> <span class="text-muted">O_Neal</span> <div>当调试Web应用时,经常需要使用ide远程连接,来进行debug调试。使用Springboot内置服务器和使用Tomcat服务器是常见的应用部署方式,可以用不同的配置方式来启动远程debug模式。Springboot应用1.配置启动参数运行jar时加上debug参数,例如java-jar-Xdebug-Xrunjdwp:transport=dt_socket,address=60222,suspe</div> </li> <li><a href="/article/1772209212324118528.htm" title="spring security 权限(注解)" target="_blank">spring security 权限(注解)</a> <span class="text-muted">LaoCat__</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/springcloud/1.htm">springcloud</a><a class="tag" taget="_blank" href="/search/web%E5%90%8E%E7%AB%AF/1.htm">web后端</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/security/1.htm">security</a> <div>写在前边整理的知识点都是从其他博客中来,如有侵权,立删!参考:https://blog.csdn.net/qq_32867467/article/details/103097190正题:SpringSecurity默认是禁用注解的,要想开启注解,要在继承WebSecurityConfigurerAdapter的类加@EnableMethodSecurity注解,并在该类中将Authenticati</div> </li> <li><a href="/article/1772176109706739712.htm" title="nodejs+vue的街道办管理系统python-flask-django-php" target="_blank">nodejs+vue的街道办管理系统python-flask-django-php</a> <span class="text-muted">QQ_1963288475</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/flask/1.htm">flask</a><a class="tag" taget="_blank" href="/search/django/1.htm">django</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a> <div>在此基础上,结合现有街道办管理体系的特点,运用新技术,构建了以nodejs为基础的街道办管理信息化管理体系。首先,以需求为依据,根据需求分析结果进行了系统的设计,并将其划分为管理员和用户二种角色和多个主要模块:用户、住户信息、流动人口、住户居住、住户迁出、缴费信息、投诉维修理、处理信息、评价评分、核酸采样、预约信息等。使用目前市场主流的技术express框架进行项目构建,基于MVC开发模式,使用n</div> </li> <li><a href="/article/1772006429562044416.htm" title="spring cloud gateway k8s优雅启停" target="_blank">spring cloud gateway k8s优雅启停</a> <span class="text-muted">luffy_1993</span> <a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a> <div>通过配置readiness探针和preStophook,实现优雅启动和停止(滚动部署)1.k8s工作负载配置readinessProbe:httpGet:path:/datetimeport:8080scheme:HTTPinitialDelaySeconds:30timeoutSeconds:1periodSeconds:30successThreshold:1failureThreshold:</div> </li> <li><a href="/article/1771868725453062144.htm" title="moba客户端开发面经" target="_blank">moba客户端开发面经</a> <span class="text-muted">Unity游戏开发</span> <a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91/1.htm">游戏开发</a><a class="tag" taget="_blank" href="/search/unity/1.htm">unity</a> <div>1、Lua:元表是什么,怎么实现对象继承2、OPP是什么3、mvc结构4、C#:list和array区别和使用场景5、项目:(1)ui框架类设计,ui层级管理怎么做,对象初始化内存占用这样做高,资源是怎么加载的(2)背包数据室怎么加载的,mvc怎么使用的,怎么性能优化的(3)ui的一些优化方式,动静分离,不使用透明,排序减少batch6、帧同步和状态同步介绍:(1)用什么协议,这俩什么区别(2)网</div> </li> <li><a href="/article/1771856892746858496.htm" title="Websocket + Vue使用" target="_blank">Websocket + Vue使用</a> <span class="text-muted">人间观察师</span> <a class="tag" taget="_blank" href="/search/websocket/1.htm">websocket</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>这里有一篇文档可以参考一下>闪现POM文件org.springframework.bootspring-boot-starter-websocket2.7.0WebSocketConfig配置importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configura</div> </li> <li><a href="/article/1771792452601053184.htm" title="[套路] 浏览器引入Vue.js场景-WangEditor富文本编辑器的使用 (永久免费)" target="_blank">[套路] 浏览器引入Vue.js场景-WangEditor富文本编辑器的使用 (永久免费)</a> <span class="text-muted">Grandpa_Rick</span> <a class="tag" taget="_blank" href="/search/%E5%A5%97%E8%B7%AF/1.htm">套路</a><a class="tag" taget="_blank" href="/search/front/1.htm">front</a><a class="tag" taget="_blank" href="/search/end/1.htm">end</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/wangEditor/1.htm">wangEditor</a> <div>系列文章目录[套路]el-table多选属性实现单选效果[套路]基于服务内存实现的中文拼音混合查询[套路]Bypass滑块验证码目录系列文章目录前言一、实现1.1场景1.2Window对象简介1.3引入WangEditor1.4页面配置前言公司使用freemarker的老旧SpringBootWeb后台项目,前两年通过浏览器引入js的方式使用Vue简单升级了下,方便迭代功能.近期一个很简单的功能需</div> </li> <li><a href="/article/1771781879792467968.htm" title="spring boot高级运用:使用Spring Cloud Config实现集中式配置管理,动态管理应用程序配置" target="_blank">spring boot高级运用:使用Spring Cloud Config实现集中式配置管理,动态管理应用程序配置</a> <span class="text-muted">岚珂瓜呱</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>使用SpringCloudConfig实现集中式配置管理,动态管理应用程序配置使用SpringCloudConfig实现集中式配置管理非常强大,它允许您将应用程序的配置从代码中分离出来,并集中存储在一个或多个配置存储库中(例如Git,SVN等)。下面是一个简单的示例,演示如何使用SpringCloudConfig来实现这一点:创建配置存储库:在您的版本控制系统(例如Git)中创建一个配置存储库,用</div> </li> <li><a href="/article/1770965590861742080.htm" title="springboot项目学习-瑞吉外卖(1)" target="_blank">springboot项目学习-瑞吉外卖(1)</a> <span class="text-muted">两仪式quq</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%91%9E%E5%90%89%E5%A4%96%E5%8D%96/1.htm">瑞吉外卖</a> <div>第一天任务如下:建立基本架构完成登录、退出功能注意:本博客没有使用网上教程里的mybatis-plus,使用的是mybatis;数据库连接池也没有使用教程里的druid,使用的是spring自带的连接池基本架构common包:存放的通用类R,用来给前端返回Json格式的数据config包:存放配置类,在今天的任务中主要解决静态资源路径映射问题controller包entity包:存放实体类mapp</div> </li> <li><a href="/article/1770911719028228096.htm" title="springboot中get post put delete 请求区别详解" target="_blank">springboot中get post put delete 请求区别详解</a> <span class="text-muted">developerFBI</span> <a class="tag" taget="_blank" href="/search/JAVA/1.htm">JAVA</a><a class="tag" taget="_blank" href="/search/Springboot/1.htm">Springboot</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>Spring4.3中引进了{@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping}来帮助简化常用的HTTP方法的映射并更好地表达被注解方法的语义。1.@GetMapping:处理get请求,传统的RequestMapping来编写应该是@RequestMapping(value=“/get/{id}”,method=Re</div> </li> <li><a href="/article/1770875597107560448.htm" title="第10讲_Spring对Dao的支持" target="_blank">第10讲_Spring对Dao的支持</a> <span class="text-muted">吴国友</span> <div>Spring框架优秀就是在于MVC开发的时候一旦需要对底层的数据库操作,它可以很好的支持JDBC技术,还有现在主流的ORM框架(Hibernate,MyBatis)技术。重点先介绍Spring对JDBC支持。在Spring对JDBC支持中提供了一个模板JdbcTemplate,此模板封装了对JDBC操作的许多方法,且消除了忽视资源释放而引起的漏洞Spring对JDBC操作需要导入的jar(开发环境</div> </li> <li><a href="/article/1770356457712189440.htm" title="05. spring-boot对spring-mvc的自动配置" target="_blank">05. spring-boot对spring-mvc的自动配置</a> <span class="text-muted">马晓钧</span> <div>spring-mvc的自动配置viewResolver:视图解析器:根据方法的返回值得到视图对象(View)。//会将容器中已有的ViewResolver和自己定义的ViewResolver全部add进去ContentNegotiatingViewResolver自定义视图解析器://需要实现ViewResolver,并注入进容器@ConfigurationpublicclassViewConfi</div> </li> <li><a href="/article/1770279302894518272.htm" title="rabbitmq发送json消息" target="_blank">rabbitmq发送json消息</a> <span class="text-muted">陌以然I</span> <a class="tag" taget="_blank" href="/search/rabbitmq/1.htm">rabbitmq</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a> <div>rabbitmq发送json格式消息packageorg.secp.rabbitmq.exchange;importorg.springframework.amqp.core.Binding;importorg.springframework.amqp.core.BindingBuilder;importorg.springframework.amqp.core.Queue;importorg.s</div> </li> <li><a href="/article/1770255640363597824.htm" title="【Elasticsearch】从零开始搭建ES8集群并且集成到Springboot,更好的服务电商类等需要全文索引的项目(一)" target="_blank">【Elasticsearch】从零开始搭建ES8集群并且集成到Springboot,更好的服务电商类等需要全文索引的项目(一)</a> <span class="text-muted">Smily清禾酥酒</span> <a class="tag" taget="_blank" href="/search/%E4%B8%AD%E9%97%B4%E4%BB%B6/1.htm">中间件</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/lucene/1.htm">lucene</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/1.htm">全文检索</a> <div>从零开始搭建Elasticsearch集群(一)从零开始搭建Elasticsearch8.6集群(一)简单介绍下Elasticsearch,以及为何使用它下载Elasticsearch准备服务器解压安装配置文件elasticsearch.yml修改调整JVM运行内存设置密码证书认证1.生成证书2.生成秘钥3.迁移凭证地址到config目录下4.其他集群都要将这个凭证移动到这个ES安装的config</div> </li> <li><a href="/article/1770227443022495744.htm" title="JdkDynamicAopProxy学习" target="_blank">JdkDynamicAopProxy学习</a> <span class="text-muted">weixin_44877172</span> <a class="tag" taget="_blank" href="/search/Spring/1.htm">Spring</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>简介JdkDynamicAopProxy#invoke是SpringAOP(面向切面编程)框架中用于动态代理的核心方法之一。这个方法是在使用JDK动态代理时,通过JdkDynamicAopProxy类创建的代理对象上调用目标方法时,被自动调用的。以下是该方法的解析:方法签名首先,我们先看一下invoke方法的签名:publicObjectinvoke(Objectproxy,Methodmetho</div> </li> <li><a href="/article/1770188673397096448.htm" title="某小厂java后端初面,记录一下" target="_blank">某小厂java后端初面,记录一下</a> <span class="text-muted">bpmh</span> <a class="tag" taget="_blank" href="/search/Java%E5%BC%80%E5%8F%911%E5%A4%A91%E9%81%93%E9%9D%A2%E8%AF%95%E9%A2%98/1.htm">Java开发1天1道面试题</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a> <div>好吧,,,,,本人很菜,再接再励吧,继续刷。简单记录一下面试题,未亡羊补牢呗。1.liftjoin;innerjoin;rightjoin的区别2.union和unionall的区别3.like查询会走索引吗?4.主键和索引的区别5.count(*),count(1),count(ID)的区别6.exists了解吗?作用是什么7.线程池了解吗?8.spring创建的bean是单例模式还是多例模式,</div> </li> <li><a href="/article/1770137194695032832.htm" title="Vue+SpringBoot打造数据可视化的智慧河南大屏" target="_blank">Vue+SpringBoot打造数据可视化的智慧河南大屏</a> <span class="text-muted">桑程程</span> <a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">信息可视化</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/cloud/1.htm">cloud</a> <div>目录一、摘要1.1项目介绍1.2项目录屏二、功能模块三、系统展示四、核心代码4.1数据模块A4.2数据模块B4.3数据模块C4.4数据模块D4.5数据模块E五、免责说明一、摘要1.1项目介绍基于JAVA+Vue+SpringBoot+MySQL的数据可视化的智慧河南大屏,包含了GDP、人口、土地面积、企业数、人均收入数据排行、地图展示等模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、</div> </li> <li><a href="/article/1770103077970444288.htm" title="spring boot 验证码源代码,直接复制使用" target="_blank">spring boot 验证码源代码,直接复制使用</a> <span class="text-muted">古猿写代码</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>使用springboot实现验证码源代码,直接复制使用publicvoidgetCodeImage(HttpServletResponseresponse){//随机生成4位验证码RandomGeneratorrandomGenerator=newRandomGenerator("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW</div> </li> <li><a href="/article/1770102951768031232.htm" title="如何在Spring Boot应用中高效集成Spring Cache与Redis实现高性能缓存机制" target="_blank">如何在Spring Boot应用中高效集成Spring Cache与Redis实现高性能缓存机制</a> <span class="text-muted">yangqjiayou</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>一、引言在现代Web应用程序开发中,缓存是一种常见的优化手段,能够显著提升系统性能,减轻数据库负载。SpringCache作为Spring框架内建的缓存抽象层,提供了一种简单易用的方式来统一处理缓存逻辑。而Redis作为一种高性能的内存键值存储系统,经常被选作SpringCache的后端存储。本文将通过一个真实的项目实例,详细介绍SpringCache的使用方法及其与Redis的集成过程。二、Sp</div> </li> <li><a href="/article/74.htm" title="sql统计相同项个数并按名次显示" target="_blank">sql统计相同项个数并按名次显示</a> <span class="text-muted">朱辉辉33</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a> <div>现在有如下这样一个表: A表 ID Name time ------------------------------ 0001 aaa 2006-11-18 0002 ccc 2006-11-18 0003 eee 2006-11-18 0004 aaa 2006-11-18 0005 eee 2006-11-18 0004 aaa 2006-11-18 0002 ccc 20</div> </li> <li><a href="/article/201.htm" title="Android+Jquery Mobile学习系列-目录" target="_blank">Android+Jquery Mobile学习系列-目录</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/JQuery+Mobile/1.htm">JQuery Mobile</a> <div>最近在研究学习基于Android的移动应用开发,准备给家里人做一个应用程序用用。向公司手机移动团队咨询了下,觉得使用Android的WebView上手最快,因为WebView等于是一个内置浏览器,可以基于html页面开发,不用去学习Android自带的七七八八的控件。然后加上Jquery mobile的样式渲染和事件等,就能非常方便的做动态应用了。   从现在起,往后一段时间,我打算</div> </li> <li><a href="/article/328.htm" title="如何给线程池命名" target="_blank">如何给线程池命名</a> <span class="text-muted">daysinsun</span> <a class="tag" taget="_blank" href="/search/%E7%BA%BF%E7%A8%8B%E6%B1%A0/1.htm">线程池</a> <div>        在系统运行后,在线程快照里总是看到线程池的名字为pool-xx,这样导致很不好定位,怎么给线程池一个有意义的名字呢。参照ThreadPoolExecutor类的ThreadFactory,自己实现ThreadFactory接口,重写newThread方法即可。参考代码如下:     public class Named</div> </li> <li><a href="/article/455.htm" title="IE 中"HTML Parsing Error:Unable to modify the parent container element before the" target="_blank">IE 中"HTML Parsing Error:Unable to modify the parent container element before the</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/%E8%A7%A3%E6%9E%90/1.htm">解析</a><a class="tag" taget="_blank" href="/search/error/1.htm">error</a><a class="tag" taget="_blank" href="/search/readyState/1.htm">readyState</a> <div>  错误: IE 中"HTML Parsing Error:Unable to modify the parent container element before the child element is closed"     现象: 同事之间几个IE 测试情况下,有的报这个错,有的不报。经查询资料后,可归纳以下原因。</div> </li> <li><a href="/article/582.htm" title="java上传" target="_blank">java上传</a> <span class="text-muted">g21121</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>我们在做web项目中通常会遇到上传文件的情况,用struts等框架的会直接用的自带的标签和组件,今天说的是利用servlet来完成上传。 我们这里利用到commons-fileupload组件,相关jar包可以取apache官网下载:http://commons.apache.org/ 下面是servlet的代码: //定义一个磁盘文件工厂 DiskFileItemFactory fact</div> </li> <li><a href="/article/709.htm" title="SpringMVC配置学习" target="_blank">SpringMVC配置学习</a> <span class="text-muted">510888780</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/mvc/1.htm">mvc</a> <div>spring MVC配置详解 现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了。不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理。   一、Spring MVC环境搭建:(Spring 2.5.6 + Hi</div> </li> <li><a href="/article/836.htm" title="spring mvc-jfreeChart 柱图(1)" target="_blank">spring mvc-jfreeChart 柱图(1)</a> <span class="text-muted">布衣凌宇</span> <a class="tag" taget="_blank" href="/search/jfreechart/1.htm">jfreechart</a> <div>第一步:下载jfreeChart包,注意是jfreeChart文件lib目录下的,jcommon-1.0.23.jar和jfreechart-1.0.19.jar两个包即可; 第二步:配置web.xml; web.xml代码如下 <servlet>     <servlet-name>jfreechart</servlet-nam</div> </li> <li><a href="/article/963.htm" title="我的spring学习笔记13-容器扩展点之PropertyPlaceholderConfigurer" target="_blank">我的spring学习笔记13-容器扩展点之PropertyPlaceholderConfigurer</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/Spring3/1.htm">Spring3</a> <div>PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是BeanFactoryPostProcessor接口的一个实现。关于BeanFactoryPostProcessor和BeanPostProcessor类似。我会在其他地方介绍。PropertyPlaceholderConfigurer可以将上下文(配置文件)中的属性值放在另一个单独的标准java P</div> </li> <li><a href="/article/1090.htm" title="java 线程池使用 Runnable&Callable&Future" target="_blank">java 线程池使用 Runnable&Callable&Future</a> <span class="text-muted">antlove</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/Runnable/1.htm">Runnable</a><a class="tag" taget="_blank" href="/search/callable/1.htm">callable</a><a class="tag" taget="_blank" href="/search/future/1.htm">future</a> <div>1. 创建线程池 ExecutorService executorService = Executors.newCachedThreadPool();   2. 执行一次线程,调用Runnable接口实现 Future<?> future = executorService.submit(new DefaultRunnable()); System.out.prin</div> </li> <li><a href="/article/1217.htm" title="XML语法元素结构的总结" target="_blank">XML语法元素结构的总结</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/xml/1.htm">xml</a><a class="tag" taget="_blank" href="/search/%E6%A0%91%E7%BB%93%E6%9E%84/1.htm">树结构</a> <div>1.XML介绍1969年   gml (主要目的是要在不同的机器进行通信的数据规范)1985年   sgml  standard generralized markup language1993年   html(www网)1998年  xml   extensible markup language</div> </li> <li><a href="/article/1344.htm" title="改变eclipse编码格式" target="_blank">改变eclipse编码格式</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A0%81%E6%A0%BC%E5%BC%8F/1.htm">编码格式</a> <div>1.改变整个工作空间的编码格式         改变整个工作空间的编码格式,这样以后新建的文件也是新设置的编码格式。         Eclipse->window->preferences->General->workspace-</div> </li> <li><a href="/article/1471.htm" title="javascript中return的设计缺陷" target="_blank">javascript中return的设计缺陷</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a> <div>代码1: <script> var gisService = (function(window) { return { name:function () { alert(1); } }; })(this); gisService.name(); &l</div> </li> <li><a href="/article/1598.htm" title="【持久化框架MyBatis3八】Spring集成MyBatis3" target="_blank">【持久化框架MyBatis3八】Spring集成MyBatis3</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/Mybatis3/1.htm">Mybatis3</a> <div>pom.xml配置 Maven的pom中主要包括: MyBatis MyBatis-Spring Spring MySQL-Connector-Java Druid applicationContext.xml配置   <?xml version="1.0" encoding="UTF-8"?> &</div> </li> <li><a href="/article/1725.htm" title="java web项目启动时自动加载自定义properties文件" target="_blank">java web项目启动时自动加载自定义properties文件</a> <span class="text-muted">bitray</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/%E7%9B%91%E5%90%AC%E5%99%A8/1.htm">监听器</a><a class="tag" taget="_blank" href="/search/%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84/1.htm">相对路径</a> <div>创建一个类 public class ContextInitListener implements ServletContextListener 使得该类成为一个监听器。用于监听整个容器生命周期的,主要是初始化和销毁的。 类创建后要在web.xml配置文件中增加一个简单的监听器配置,即刚才我们定义的类。 <listener> <des</div> </li> <li><a href="/article/1852.htm" title="用nginx区分文件大小做出不同响应" target="_blank">用nginx区分文件大小做出不同响应</a> <span class="text-muted">ronin47</span> <div>昨晚和前21v的同事聊天,说到我离职后一些技术上的更新。其中有个给某大客户(游戏下载类)的特殊需求设计,因为文件大小差距很大——估计是大版本和补丁的区别——又走的是同一个域名,而squid在响应比较大的文件时,尤其是初次下载的时候,性能比较差,所以拆成两组服务器,squid服务于较小的文件,通过pull方式从peer层获取,nginx服务于较大的文件,通过push方式由peer层分发同步。外部发布</div> </li> <li><a href="/article/1979.htm" title="java-67-扑克牌的顺子.从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的.2-10为数字本身,A为1,J为11,Q为12,K为13,而大" target="_blank">java-67-扑克牌的顺子.从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的.2-10为数字本身,A为1,J为11,Q为12,K为13,而大</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>package com.ljn.base; import java.util.Arrays; import java.util.Random; public class ContinuousPoker { /** * Q67 扑克牌的顺子 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。 * 2-10为数字本身,A为1,J为1</div> </li> <li><a href="/article/2106.htm" title="翟鸿燊老师语录" target="_blank">翟鸿燊老师语录</a> <span class="text-muted">ccii</span> <a class="tag" taget="_blank" href="/search/%E7%BF%9F%E9%B8%BF%E7%87%8A/1.htm">翟鸿燊</a> <div>一、国学应用智慧TAT之亮剑精神A 1. 角色就是人格     就像你一回家的时候,你一进屋里面,你已经是儿子,是姑娘啦,给老爸老妈倒怀水吧,你还觉得你是老总呢?还拿派呢?就像今天一样,你们往这儿一坐,你们之间是什么,同学,是朋友。     还有下属最忌讳的就是领导向他询问情况的时候,什么我不知道,我不清楚,该你知道的你凭什么不知道</div> </li> <li><a href="/article/2233.htm" title="[光速与宇宙]进行光速飞行的一些问题" target="_blank">[光速与宇宙]进行光速飞行的一些问题</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/%E9%97%AE%E9%A2%98/1.htm">问题</a> <div>      在人类整体进入宇宙时代,即将开展深空宇宙探索之前,我有几个猜想想告诉大家     仅仅是猜想。。。未经官方证实      1:要在宇宙中进行光速飞行,必须首先获得宇宙中的航行通行证,而这个航行通行证并不是我们平常认为的那种带钢印的证书,是什么呢? 下面我来告诉</div> </li> <li><a href="/article/2360.htm" title="oracle undo解析" target="_blank">oracle undo解析</a> <span class="text-muted">cwqcwqmax9</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a> <div>oracle undo解析2012-09-24 09:02:01     我来说两句       作者:虫师收藏    我要投稿 Undo是干嘛用的?         &nb</div> </li> <li><a href="/article/2487.htm" title="java中各种集合的详细介绍" target="_blank">java中各种集合的详细介绍</a> <span class="text-muted">dashuaifu</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E5%90%88/1.htm">集合</a> <div>一,java中各种集合的关系图 Collection       接口的接口     对象的集合  ├ List           子接口   &n</div> </li> <li><a href="/article/2614.htm" title="卸载windows服务的方法" target="_blank">卸载windows服务的方法</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/service/1.htm">service</a> <div>卸载Windows服务的方法 在Windows中,有一类程序称为服务,在操作系统内核加载完成后就开始加载。这里程序往往运行在操作系统的底层,因此资源占用比较大、执行效率比较高,比较有代表性的就是杀毒软件。但是一旦因为特殊原因不能正确卸载这些程序了,其加载在Windows内的服务就不容易删除了。即便是删除注册表中的相 应项目,虽然不启动了,但是系统中仍然存在此项服务,只是没有加载而已。如果安装其他</div> </li> <li><a href="/article/2741.htm" title="Warning: The Copy Bundle Resources build phase contains this target's Info.plist" target="_blank">Warning: The Copy Bundle Resources build phase contains this target's Info.plist</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/ios/1.htm">ios</a><a class="tag" taget="_blank" href="/search/xcode/1.htm">xcode</a> <div>    http://developer.apple.com/iphone/library/qa/qa2009/qa1649.html Excerpt: You are getting this warning because you probably added your Info.plist file to your Copy Bundle </div> </li> <li><a href="/article/2868.htm" title="2014之C++学习笔记(一)" target="_blank">2014之C++学习笔记(一)</a> <span class="text-muted">Etwo</span> <a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/Etwo/1.htm">Etwo</a><a class="tag" taget="_blank" href="/search/Etwo/1.htm">Etwo</a><a class="tag" taget="_blank" href="/search/iterator/1.htm">iterator</a><a class="tag" taget="_blank" href="/search/%E8%BF%AD%E4%BB%A3%E5%99%A8/1.htm">迭代器</a> <div>        已经有很长一段时间没有写博客了,可能大家已经淡忘了Etwo这个人的存在,这一年多以来,本人从事了AS的相关开发工作,但最近一段时间,AS在天朝的没落,相信有很多码农也都清楚,现在的页游基本上达到饱和,手机上的游戏基本被unity3D与cocos占据,AS基本没有容身之处。so。。。最近我并不打算直接转型</div> </li> <li><a href="/article/2995.htm" title="js跨越获取数据问题记录" target="_blank">js跨越获取数据问题记录</a> <span class="text-muted">haifengwuch</span> <a class="tag" taget="_blank" href="/search/jsonp/1.htm">jsonp</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a> <div>js的跨越问题,普通的ajax无法获取服务器返回的值。   第一种解决方案,通过getson,后台配合方式,实现。 Java后台代码: protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String ca</div> </li> <li><a href="/article/3122.htm" title="蓝色jQuery导航条" target="_blank">蓝色jQuery导航条</a> <span class="text-muted">ini</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/html5/1.htm">html5</a> <div>效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/39.htmHTML文件代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>jQuery鼠标悬停上下滑动导航条 - 柯乐义<</div> </li> <li><a href="/article/3249.htm" title="linux部署jdk,tomcat,mysql" target="_blank">linux部署jdk,tomcat,mysql</a> <span class="text-muted">kerryg</span> <a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div>1、安装java环境jdk:     一般系统都会默认自带的JDK,但是不太好用,都会卸载了,然后重新安装。    1.1)、卸载:      (rpm -qa :查询已经安装哪些软件包;        rmp -q 软件包:查询指定包是否已</div> </li> <li><a href="/article/3376.htm" title="DOMContentLoaded VS onload VS onreadystatechange" target="_blank">DOMContentLoaded VS onload VS onreadystatechange</a> <span class="text-muted">mutongwu</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/js/1.htm">js</a> <div>1. DOMContentLoaded 在页面html、script、style加载完毕即可触发,无需等待所有资源(image/iframe)加载完毕。(IE9+) 2. onload是最早支持的事件,要求所有资源加载完毕触发。 3. onreadystatechange 开始在IE引入,后来其它浏览器也有一定的实现。涉及以下 document , applet, embed, fra</div> </li> <li><a href="/article/3503.htm" title="sql批量插入数据" target="_blank">sql批量插入数据</a> <span class="text-muted">qifeifei</span> <a class="tag" taget="_blank" href="/search/%E6%89%B9%E9%87%8F%E6%8F%92%E5%85%A5/1.htm">批量插入</a> <div>hi,   自己在做工程的时候,遇到批量插入数据的数据修复场景。我的思路是在插入前准备一个临时表,临时表的整理就看当时的选择条件了,临时表就是要插入的数据集,最后再批量插入到数据库中。    WITH tempT AS ( SELECT item_id AS combo_id, item_id, now() AS create_date FROM a</div> </li> <li><a href="/article/3630.htm" title="log4j打印日志文件 如何实现相对路径到 项目工程下" target="_blank">log4j打印日志文件 如何实现相对路径到 项目工程下</a> <span class="text-muted">thinkfreer</span> <a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/log4j/1.htm">log4j</a><a class="tag" taget="_blank" href="/search/%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">应用服务器</a><a class="tag" taget="_blank" href="/search/%E6%97%A5%E5%BF%97/1.htm">日志</a> <div>最近为了实现统计一个网站的访问量,记录用户的登录信息,以方便站长实时了解自己网站的访问情况,选择了Apache 的log4j,但是在选择相对路径那块 卡主了,X度了好多方法(其实大多都是一样的内用,还一个字都不差的),都没有能解决问题,无奈搞了2天终于解决了,与大家分享一下 需求: 用户登录该网站时,把用户的登录名,ip,时间。统计到一个txt文档里,以方便其他系统调用此txt。项目名</div> </li> <li><a href="/article/3757.htm" title="linux下mysql-5.6.23.tar.gz安装与配置" target="_blank">linux下mysql-5.6.23.tar.gz安装与配置</a> <span class="text-muted">笑我痴狂</span> <a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/unix/1.htm">unix</a> <div>1.卸载系统默认的mysql [root@localhost ~]# rpm -qa | grep mysql mysql-libs-5.1.66-2.el6_3.x86_64 mysql-devel-5.1.66-2.el6_3.x86_64 mysql-5.1.66-2.el6_3.x86_64 [root@localhost ~]# rpm -e mysql-libs-5.1</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>