Freemarker自定义指令把java对象转成json

1、前言

使用Freemarker做模板构建页面是比较简单的,但在某些复杂的场景下需要在js中使用spring 中的model对象是个问题。

但是js不认识java对象。需要用Freemarker自定义函数去解决这个问题

2、项目构建

 

 

 构建web应用

3.1、添加fastJson依赖

      <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.57</version>
        </dependency>

整个pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.whwe</groupId>
    <artifactId>web-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>web-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.57</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2、配置webMvc

package com.whwe.webdemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

/**
 * @ClassName WebMvcConfig
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/19 9:32
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    /**
     * Override this method to add resource handlers for serving static resources.
     *
     * @param registry
     * @see ResourceHandlerRegistry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/");
        registry.addResourceHandler("/statics/**").addResourceLocations("classpath:/statics/");
        super.addResourceHandlers(registry);
    }

    /**
     * Override this method to configure cross origin requests processing.
     *
     * @param registry
     * @see CorsRegistry
     * @since 4.2
     */
    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        super.addCorsMappings(registry);
    }
    /**
     * Override this method to add Spring MVC interceptors for
     * pre- and post-processing of controller invocation.
     *
     * @param registry
     * @see InterceptorRegistry
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
    }
}

3.3、自定义java对象转成json的方法

package com.whwe.webdemo.json;

import com.alibaba.fastjson.JSON;

/**
 * @ClassName MyJson
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/19 14:12
 */
public class MyJson {
    public static String toJson(Object src) {
        String json = JSON.toJSONString(src);
        return json;
    }
}

3.4、配置Freemarker的配置

FreeMarker内部使用的变量的类型都实现了freemarker.template.TemplateModel接口。

我们需要把我们刚才的自定义类包装成TemplateModel的子类TemplateHashModel

package com.whwe.webdemo.json;

import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.*;
import lombok.extern.log4j.Log4j2;

import java.util.HashMap;
import java.util.Map;
@Log4j2
public class FreemarkerStaticModels extends HashMap<String, Object> {

	public FreemarkerStaticModels(Map<String, String> classMap) {
		for (String key : classMap.keySet()) {
			put(key, getModel(classMap.get(key)));
		}
	}
	private TemplateHashModel getModel(String packageName) {
		BeansWrapper wrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_28).build();
		TemplateHashModel fileStatics=null;
		try {
			fileStatics = (TemplateHashModel)  wrapper.getStaticModels().get(packageName);
			return fileStatics;
		} catch (TemplateModelException e) {
			log.error(e.toString());
		}
		return fileStatics;
	}
}

自定义视图解析,配置freemarker的配置

package com.whwe.webdemo.config;

import com.whwe.webdemo.json.FreemarkerStaticModels;
import freemarker.template.TemplateException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;

@Configuration
public class FreeMarkerConfig {


    @Bean
    public ViewResolver viewResolverFtl() {
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
        resolver.setCache(false);
        resolver.setViewClass(FreeMarkerView.class);
        resolver.setRequestContextAttribute("re");
        resolver.setExposeRequestAttributes(true);
        resolver.setExposeSessionAttributes(true);
        resolver.setSuffix(".ftl");
        resolver.setContentType("text/html;charset=UTF-8");
        resolver.setOrder(0);

        //添加自定义解析器
        resolver.setAttributesMap(new FreemarkerStaticModels(new HashMap<String, String>() {{
            put("Json", "com.whwe.webdemo.json.MyJson");
        }}));
        return resolver;
    }



    @Bean
    public FreeMarkerConfigurer freemarkerConfig() throws IOException, TemplateException {
        FreeMarkerConfigurationFactory factory = new FreeMarkerConfigurationFactory();
        factory.setTemplateLoaderPath("classpath:/view/");
        factory.setDefaultEncoding("UTF-8");
        factory.setPreferFileSystemAccess(false);
        FreeMarkerConfigurer result = new FreeMarkerConfigurer();
        freemarker.template.Configuration configuration = factory.createConfiguration();
        configuration.setClassicCompatible(true);
        result.setConfiguration(configuration);
        Properties settings = new Properties();
        settings.put("template_update_delay", "0");
        settings.put("default_encoding", "UTF-8");
        settings.put("number_format", "0.######");
        settings.put("classic_compatible", true);
        settings.put("template_exception_handler", "ignore");
        result.setFreemarkerSettings(settings);
        return result;
    }

}

3.5、添加测试页面

index.ftl

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎</title>
</head>
<#assign base=request.contextPath />
<script src="${base}/js/jquery-3.4.0.min.js" type="text/javascript" ></script>
<body>
<div>
    <h1>欢迎!</h1>
</div>


<script>
var user=${Json.toJson(user)};
console.log(user)
</script>
</body>
</html>

测试

新建测试controller

package com.whwe.webdemo.controller;

import com.whwe.webdemo.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @ClassName WebController
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/19 10:12
 */
@Controller
public class WebController {
    @RequestMapping(value = "test")
    public String test(Model model) {
        User user=new User();
        user.setAge(11);
        user.setName("zhangsan");
        model.addAttribute("user",user);
        return "index";
    }
}
package com.whwe.webdemo.bean;

import lombok.Data;

/**
 * @ClassName User
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/19 14:31
 */
@Data
public class User {
    private String name;
    private int age;

}

发布了61 篇原创文章 · 获赞 48 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/hzau_itdog/article/details/89400804