哪个网站的字体做的特别好资讯网站 整体ui

pingmian/2025/10/9 16:50:54/文章来源:
哪个网站的字体做的特别好,资讯网站 整体ui,wordpress 超过2m,郑州网站建设公司排行app端文章查看#xff0c;静态化freemarker,分布式文件系统minIO 1)文章列表加载 1.1)需求分析 文章布局展示 1.2)表结构分析 ap_article 文章基本信息表 ap_article_config 文章配置表 ap_article_content 文章内容表 三张表关系分析 1.3)导入文章数据库 1.3.1)导入数据…app端文章查看静态化freemarker,分布式文件系统minIO 1)文章列表加载 1.1)需求分析 文章布局展示 1.2)表结构分析 ap_article 文章基本信息表 ap_article_config 文章配置表 ap_article_content 文章内容表 三张表关系分析 1.3)导入文章数据库 1.3.1)导入数据库 查看当天资料文件夹在数据库连接工具中执行leadnews_article.sql 1.3.2)导入对应的实体类 ap_article文章表对应实体 package com.heima.model.article.pojos;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;import java.io.Serializable; import java.util.Date;/*** p* 文章信息表存储已发布的文章* /p** author itheima*/Data TableName(ap_article) public class ApArticle implements Serializable {TableId(value id,type IdType.ID_WORKER)private Long id;/*** 标题*/private String title;/*** 作者id*/TableField(author_id)private Long authorId;/*** 作者名称*/TableField(author_name)private String authorName;/*** 频道id*/TableField(channel_id)private Integer channelId;/*** 频道名称*/TableField(channel_name)private String channelName;/*** 文章布局 0 无图文章 1 单图文章 2 多图文章*/private Short layout;/*** 文章标记 0 普通文章 1 热点文章 2 置顶文章 3 精品文章 4 大V 文章*/private Byte flag;/*** 文章封面图片 多张逗号分隔*/private String images;/*** 标签*/private String labels;/*** 点赞数量*/private Integer likes;/*** 收藏数量*/private Integer collection;/*** 评论数量*/private Integer comment;/*** 阅读数量*/private Integer views;/*** 省市*/TableField(province_id)private Integer provinceId;/*** 市区*/TableField(city_id)private Integer cityId;/*** 区县*/TableField(county_id)private Integer countyId;/*** 创建时间*/TableField(created_time)private Date createdTime;/*** 发布时间*/TableField(publish_time)private Date publishTime;/*** 同步状态*/TableField(sync_status)private Boolean syncStatus;/*** 来源*/private Boolean origin;/*** 静态页面地址*/TableField(static_url)private String staticUrl; }ap_article_config文章配置对应实体类 package com.heima.model.article.pojos;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;import java.io.Serializable;/*** p* APP已发布文章配置表* /p** author itheima*/Data TableName(ap_article_config) public class ApArticleConfig implements Serializable {TableId(value id,type IdType.ID_WORKER)private Long id;/*** 文章id*/TableField(article_id)private Long articleId;/*** 是否可评论* true: 可以评论 1* false: 不可评论 0*/TableField(is_comment)private Boolean isComment;/*** 是否转发* true: 可以转发 1* false: 不可转发 0*/TableField(is_forward)private Boolean isForward;/*** 是否下架* true: 下架 1* false: 没有下架 0*/TableField(is_down)private Boolean isDown;/*** 是否已删除* true: 删除 1* false: 没有删除 0*/TableField(is_delete)private Boolean isDelete; }ap_article_content 文章内容对应的实体类 package com.heima.model.article.pojos;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;import java.io.Serializable;Data TableName(ap_article_content) public class ApArticleContent implements Serializable {TableId(value id,type IdType.ID_WORKER)private Long id;/*** 文章id*/TableField(article_id)private Long articleId;/*** 文章内容*/private String content; }1.4)实现思路 1,在默认频道展示10条文章信息 2,可以切换频道查看不同种类文章 3,当用户下拉可以加载最新的文章分页本页文章列表中发布时间为最大的时间为依据 4,当用户上拉可以加载更多的文章信息按照发布时间本页文章列表中发布时间最小的时间为依据 5如果是当前频道的首页前端传递默认参数 maxBehotTime0毫秒 minBehotTime20000000000000毫秒—2063年 1.5)接口定义 加载首页加载更多加载最新接口路径/api/v1/article/load/api/v1/article/loadmore/api/v1/article/loadnew请求方式POSTPOSTPOST参数ArticleHomeDtoArticleHomeDtoArticleHomeDto响应结果ResponseResultResponseResultResponseResult ArticleHomeDto package com.heima.model.article.dtos;import lombok.Data;import java.util.Date;Data public class ArticleHomeDto {// 最大时间Date maxBehotTime;// 最小时间Date minBehotTime;// 分页sizeInteger size;// 频道IDString tag; }1.6)功能实现 1.6.1)导入heima-leadnews-article微服务资料在当天的文件夹中 注意需要在heima-leadnews-service的pom文件夹中添加子模块信息如下 modulesmoduleheima-leadnews-user/modulemoduleheima-leadnews-article/module /modules在idea中的maven中更新一下如果工程还是灰色的需要在重新添加文章微服务的pom文件操作步骤如下 需要在nacos中添加对应的配置 spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/leadnews_article?useUnicodetruecharacterEncodingUTF-8serverTimezoneUTCusername: rootpassword: root # 设置Mapper接口所对应的XML文件位置如果你在Mapper接口中有自定义方法需要进行该配置 mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径通过该属性可以给包中的类注册别名type-aliases-package: com.heima.model.article.pojos1.6.2)定义接口 package com.heima.article.controller.v1;import com.heima.model.article.dtos.ArticleHomeDto; import com.heima.model.common.dtos.ResponseResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/api/v1/article) public class ArticleHomeController {PostMapping(/load)public ResponseResult load(RequestBody ArticleHomeDto dto) {return null;}PostMapping(/loadmore)public ResponseResult loadMore(RequestBody ArticleHomeDto dto) {return null;}PostMapping(/loadnew)public ResponseResult loadNew(RequestBody ArticleHomeDto dto) {return null;} }1.6.3)编写mapper文件 package com.heima.article.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.heima.model.article.dtos.ArticleHomeDto; import com.heima.model.article.pojos.ApArticle; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;import java.util.List;Mapper public interface ApArticleMapper extends BaseMapperApArticle {public ListApArticle loadArticleList(Param(dto) ArticleHomeDto dto, Param(type) Short type);}对应的映射文件 在resources中新建mapper/ApArticleMapper.xml 如下配置 ?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.heima.article.mapper.ApArticleMapperresultMap idresultMap typecom.heima.model.article.pojos.ApArticleid columnid propertyid/result columntitle propertytitle/result columnauthor_id propertyauthorId/result columnauthor_name propertyauthorName/result columnchannel_id propertychannelId/result columnchannel_name propertychannelName/result columnlayout propertylayout/result columnflag propertyflag/result columnimages propertyimages/result columnlabels propertylabels/result columnlikes propertylikes/result columncollection propertycollection/result columncomment propertycomment/result columnviews propertyviews/result columnprovince_id propertyprovinceId/result columncity_id propertycityId/result columncounty_id propertycountyId/result columncreated_time propertycreatedTime/result columnpublish_time propertypublishTime/result columnsync_status propertysyncStatus/result columnstatic_url propertystaticUrl//resultMapselect idloadArticleList resultMapresultMapSELECTaa.*FROMap_article aaLEFT JOIN ap_article_config aac ON aa.id aac.article_idwhereand aac.is_delete ! 1and aac.is_down ! 1!-- loadmore --if testtype ! null and type 1and aa.publish_time ![CDATA[]] #{dto.minBehotTime}/ifif testtype ! null and type 2and aa.publish_time ![CDATA[]] #{dto.maxBehotTime}/ifif testdto.tag ! __all__and aa.channel_id #{dto.tag}/if/whereorder by aa.publish_time desclimit #{dto.size}/select/mapper1.6.4)编写业务层代码 package com.heima.article.service;import com.baomidou.mybatisplus.extension.service.IService; import com.heima.model.article.dtos.ArticleHomeDto; import com.heima.model.article.pojos.ApArticle; import com.heima.model.common.dtos.ResponseResult;import java.io.IOException;public interface ApArticleService extends IServiceApArticle {/*** 根据参数加载文章列表* param loadtype 1为加载更多 2为加载最新* param dto* return*/ResponseResult load(Short loadtype, ArticleHomeDto dto);}实现类 package com.heima.article.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.heima.article.mapper.ApArticleMapper; import com.heima.article.service.ApArticleService; import com.heima.common.constants.ArticleConstants; import com.heima.model.article.dtos.ArticleHomeDto;import com.heima.model.article.pojos.ApArticle; import com.heima.model.common.dtos.ResponseResult; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;import java.util.Date; import java.util.List;Service Transactional Slf4j public class ApArticleServiceImpl extends ServiceImplApArticleMapper, ApArticle implements ApArticleService {// 单页最大加载的数字private final static short MAX_PAGE_SIZE 50;Autowiredprivate ApArticleMapper apArticleMapper;/*** 根据参数加载文章列表* param loadtype 1为加载更多 2为加载最新* param dto* return*/Overridepublic ResponseResult load(Short loadtype, ArticleHomeDto dto) {//1.校验参数Integer size dto.getSize();if(size null || size 0){size 10;}size Math.min(size,MAX_PAGE_SIZE);dto.setSize(size);//类型参数检验if(!loadtype.equals(ArticleConstants.LOADTYPE_LOAD_MORE)!loadtype.equals(ArticleConstants.LOADTYPE_LOAD_NEW)){loadtype ArticleConstants.LOADTYPE_LOAD_MORE;}//文章频道校验if(StringUtils.isEmpty(dto.getTag())){dto.setTag(ArticleConstants.DEFAULT_TAG);}//时间校验if(dto.getMaxBehotTime() null) dto.setMaxBehotTime(new Date());if(dto.getMinBehotTime() null) dto.setMinBehotTime(new Date());//2.查询数据ListApArticle apArticles apArticleMapper.loadArticleList(dto, loadtype);//3.结果封装ResponseResult responseResult ResponseResult.okResult(apArticles);return responseResult;}}定义常量类 package com.heima.common.constants;public class ArticleConstants {public static final Short LOADTYPE_LOAD_MORE 1;public static final Short LOADTYPE_LOAD_NEW 2;public static final String DEFAULT_TAG __all__;}1.6.5)编写控制器代码 package com.heima.article.controller.v1;import com.heima.article.service.ApArticleService; import com.heima.common.constants.ArticleConstants; import com.heima.model.article.dtos.ArticleHomeDto; import com.heima.model.common.dtos.ResponseResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/api/v1/article) public class ArticleHomeController {Autowiredprivate ApArticleService apArticleService;PostMapping(/load)public ResponseResult load(RequestBody ArticleHomeDto dto) {return apArticleService.load(ArticleConstants.LOADTYPE_LOAD_MORE,dto);}PostMapping(/loadmore)public ResponseResult loadMore(RequestBody ArticleHomeDto dto) {return apArticleService.load(ArticleConstants.LOADTYPE_LOAD_MORE,dto);}PostMapping(/loadnew)public ResponseResult loadNew(RequestBody ArticleHomeDto dto) {return apArticleService.load(ArticleConstants.LOADTYPE_LOAD_NEW,dto);} }1.6.6)swagger测试或前后端联调测试 第一在app网关的微服务的nacos的配置中心添加文章微服务的路由完整配置如下 spring:cloud:gateway:globalcors:cors-configurations:[/**]: # 匹配所有请求allowedOrigins: * #跨域处理 允许所有的域allowedMethods: # 支持的方法- GET- POST- PUT- DELETEroutes:# 用户微服务- id: useruri: lb://leadnews-userpredicates:- Path/user/**filters:- StripPrefix 1# 文章微服务- id: articleuri: lb://leadnews-articlepredicates:- Path/article/**filters:- StripPrefix 1第二启动nginx直接使用前端项目测试启动文章微服务用户微服务、app网关微服务 2)freemarker 2.1) freemarker 介绍 ​ FreeMarker 是一款 模板引擎 即一种基于模板和要改变的数据 并用来生成输出文本(HTML网页电子邮件配置文件源代码等)的通用工具。 它不是面向最终用户的而是一个Java类库是一款程序员可以嵌入他们所开发产品的组件。 ​ 模板编写为FreeMarker Template Language (FTL)。它是简单的专用的语言 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示比如数据库查询和业务运算 之后模板显示已经准备好的数据。在模板中你可以专注于如何展现数据 而在模板之外可以专注于要展示什么数据。 常用的java模板引擎还有哪些 Jsp、Freemarker、Thymeleaf 、Velocity 等。 1.Jsp 为 Servlet 专用不能单独进行使用。 2.Thymeleaf 为新技术功能较为强大但是执行的效率比较低。 3.Velocity从2010年更新完 2.0 版本后便没有在更新。Spring Boot 官方在 1.4 版本后对此也不在支持虽然 Velocity 在 2017 年版本得到迭代但为时已晚。 2.2) 环境搭建快速入门 freemarker作为springmvc一种视图格式默认情况下SpringMVC支持freemarker视图格式。 需要创建Spring BootFreemarker工程用于测试模板。 2.2.1) 创建测试工程 创建一个freemarker-demo 的测试工程专门用于freemarker的功能测试与模板的测试。 pom.xml如下 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdheima-leadnews-test/artifactIdgroupIdcom.heima/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdfreemarker-demo/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-freemarker/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependency!-- lombok --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency!-- apache 对 java io 的封装工具库 --dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-io/artifactIdversion1.3.2/version/dependency/dependencies/project2.2.2) 配置文件 配置application.yml server:port: 8881 #服务端口 spring:application:name: freemarker-demo #指定服务名freemarker:cache: false #关闭模板缓存方便测试settings:template_update_delay: 0 #检查模板更新延迟时间设置为0表示立即检查如果时间大于0会有缓存不方便进行模板测试suffix: .ftl #指定Freemarker模板文件的后缀名2.2.3) 创建模型类 在freemarker的测试工程下创建模型类型用于测试 package com.heima.freemarker.entity;import lombok.Data;import java.util.Date;Data public class Student {private String name;//姓名private int age;//年龄private Date birthday;//生日private Float money;//钱包 }2.2.4) 创建模板 在resources下创建templates此目录为freemarker的默认模板存放目录。 在templates下创建模板文件 01-basic.ftl 模板中的插值表达式最终会被freemarker替换成具体的数据。 !DOCTYPE html html headmeta charsetutf-8titleHello World!/title /head body b普通文本 String 展示/bbrbr Hello ${name} br hr b对象Student中的数据展示/bbr/ 姓名${stu.name}br/ 年龄${stu.age} hr /body /html2.2.5) 创建controller 创建Controller类向Map中添加name最后返回模板文件。 package com.xuecheng.test.freemarker.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.client.RestTemplate;import java.util.Map;Controller public class HelloController {GetMapping(/basic)public String test(Model model) {//1.纯文本形式的参数model.addAttribute(name, freemarker);//2.实体类相关的参数Student student new Student();student.setName(小明);student.setAge(18);model.addAttribute(stu, student);return 01-basic;} }01-basic.ftl使用插值表达式填充数据 !DOCTYPE html html headmeta charsetutf-8titleHello World!/title /head body b普通文本 String 展示/bbrbr Hello ${name} br hr b对象Student中的数据展示/bbr/ 姓名${stu.name}br/ 年龄${stu.age} hr /body /html2.2.6) 创建启动类 package com.heima.freemarker;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class FreemarkerDemotApplication {public static void main(String[] args) {SpringApplication.run(FreemarkerDemotApplication.class,args);} }2.2.7) 测试 请求http://localhost:8881/basic 2.3) freemarker基础 2.3.1) 基础语法种类 1、注释即#-- --介于其之间的内容会被freemarker忽略 #--我是一个freemarker注释--2、插值Interpolation即 ${..} 部分,freemarker会用真实的值代替**${..}** Hello ${name}3、FTL指令和HTML标记类似名字前加#予以区分Freemarker会解析标签中的表达式或逻辑。 # FTL指令/# 4、文本仅文本信息这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析直接输出内容。 #--freemarker中的普通文本-- 我是一个普通的文本2.3.2) 集合指令List和Map 1、数据模型 在HelloController中新增如下方法 GetMapping(/list) public String list(Model model){//------------------------------------Student stu1 new Student();stu1.setName(小强);stu1.setAge(18);stu1.setMoney(1000.86f);stu1.setBirthday(new Date());//小红对象模型数据Student stu2 new Student();stu2.setName(小红);stu2.setMoney(200.1f);stu2.setAge(19);//将两个对象模型数据存放到List集合中ListStudent stus new ArrayList();stus.add(stu1);stus.add(stu2);//向model中存放List集合数据model.addAttribute(stus,stus);//------------------------------------//创建Map数据HashMapString,Student stuMap new HashMap();stuMap.put(stu1,stu1);stuMap.put(stu2,stu2);// 3.1 向model中存放Map数据model.addAttribute(stuMap, stuMap);return 02-list; }2、模板 在templates中新增02-list.ftl文件 !DOCTYPE html html headmeta charsetutf-8titleHello World!/title /head body#-- list 数据的展示 -- b展示list中的stu数据:/b br br tabletrtd序号/tdtd姓名/tdtd年龄/tdtd钱包/td/tr /table hr#-- Map 数据的展示 -- bmap数据的展示/b br/br/ a href###方式一通过map[keyname].property/abr/ 输出stu1的学生信息br/ 姓名br/ 年龄br/ br/ a href###方式二通过map.keyname.property/abr/ 输出stu2的学生信息br/ 姓名br/ 年龄br/br/ a href###遍历map中两个学生信息/abr/ tabletrtd序号/tdtd姓名/tdtd年龄/tdtd钱包/td /tr /table hr/body /html实例代码 !DOCTYPE html html headmeta charsetutf-8titleHello World!/title /head body#-- list 数据的展示 -- b展示list中的stu数据:/b br br tabletrtd序号/tdtd姓名/tdtd年龄/tdtd钱包/td/tr#list stus as stutrtd${stu_index1}/tdtd${stu.name}/tdtd${stu.age}/tdtd${stu.money}/td/tr/#list/table hr#-- Map 数据的展示 -- bmap数据的展示/b br/br/ a href###方式一通过map[keyname].property/abr/ 输出stu1的学生信息br/ 姓名${stuMap[stu1].name}br/ 年龄${stuMap[stu1].age}br/ br/ a href###方式二通过map.keyname.property/abr/ 输出stu2的学生信息br/ 姓名${stuMap.stu2.name}br/ 年龄${stuMap.stu2.age}br/br/ a href###遍历map中两个学生信息/abr/ tabletrtd序号/tdtd姓名/tdtd年龄/tdtd钱包/td/tr#list stuMap?keys as key trtd${key_index}/tdtd${stuMap[key].name}/tdtd${stuMap[key].age}/tdtd${stuMap[key].money}/td/tr/#list /table hr/body /html上面代码解释 ${k_index} index得到循环的下标使用方法是在stu后边加_index它的值是从0开始 2.3.3) if指令 ​ if 指令即判断指令是常用的FTL指令freemarker在解析时遇到if会进行判断条件为真则输出if中间的内容否则跳过内容不再输出。 指令格式 #if /if1、数据模型 使用list指令中测试数据模型判断名称为小红的数据字体显示为红色。 2、模板 tabletrtd姓名/tdtd年龄/tdtd钱包/td/tr#list stus as stutrtd ${stu.name}/tdtd${stu.age}/tdtd ${stu.mondy}/td/tr/#list/table实例代码 tabletrtd姓名/tdtd年龄/tdtd钱包/td/tr#list stus as stu #if stu.name小红tr stylecolor: redtd${stu_index}/tdtd${stu.name}/tdtd${stu.age}/tdtd${stu.money}/td/tr#else trtd${stu_index}/tdtd${stu.name}/tdtd${stu.age}/tdtd${stu.money}/td/tr/#if/#list /table3、输出 姓名为“小强”则字体颜色显示为红色。 2.3.4) 运算符 1、算数运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括: 加法 减法 -乘法 *除法 /求模 (求余) % 模板代码 b算数运算符/b br/br/1005 运算 ${100 5 }br/100 - 5 * 5运算${100 - 5 * 5}br/5 / 2运算${5 / 2}br/12 % 10运算${12 % 10}br/ hr除了 运算以外其他的运算只能和 number 数字类型的计算。 2、比较运算符 或者:判断两个值是否相等.!:判断两个值是否不等.或者gt:判断左边值是否大于右边值或者gte:判断左边值是否大于等于右边值或者lt:判断左边值是否小于右边值或者lte:判断左边值是否小于等于右边值 和 模板代码 !DOCTYPE html html headmeta charsetutf-8titleHello World!/title /head bodyb比较运算符/bbr/br/dldt / 和 ! 比较/dtdd#if xiaoming xiaoming字符串的比较 xiaoming xiaoming/#if/dddd#if 10 ! 100数值的比较 10 ! 100/#if/dd/dldldt其他比较/dtdd#if 10 gt 5 形式一使用特殊字符比较数值 10 gt 5/#if/dddd#-- 日期的比较需要通过?date将属性转为data类型才能进行比较 --#if (date1?date date2?date)形式二使用括号形式比较时间 date1?date date2?date/#if/dd/dlbr/ hr /body /htmlController 的 数据模型代码 GetMapping(operation) public String testOperation(Model model) {//构建 Date 数据Date now new Date();model.addAttribute(date1, now);model.addAttribute(date2, now);return 03-operation; }比较运算符注意 **和!**可以用于字符串、数值和日期来比较是否相等**和!**两边必须是相同类型的值,否则会产生错误字符串 x 、x 、**X**比较是不等的.因为FreeMarker是精确比较其它的运行符可以作用于数字和日期,但不能作用于字符串使用**gt等字母运算符代替会有更好的效果,因为 FreeMarker会把**解释成FTL标签的结束字符可以使用括号来避免这种情况,如:#if (xy) 3、逻辑运算符 逻辑与:逻辑或:||逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误 。 模板代码 b逻辑运算符/bbr/br/#if (10 lt 12 )( 10 gt 5 ) (10 lt 12 )( 10 gt 5 ) 显示为 true/#ifbr/br/#if !falsefalse 取反为true/#if hr2.3.5) 空值处理 1、判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false 例为防止stus为空报错可以加上判断如下 #if stus??#list stus as stu....../#list/#if2、缺失变量默认值使用 “!” 使用!要以指定一个默认值当变量为空时显示默认值 例 ${name!‘’}表示如果name为空显示空字符串。 如果是嵌套对象则建议使用括起来 例 ${(stu.bestFriend.name)!‘’}表示如果stu或bestFriend或name为空默认显示空字符串。 2.3.6) 内建函数 内建函数语法格式 变量?函数名称 1、和到某个集合的大小 ${集合名?size} 2、日期格式化 显示年月日: ${today?date} 显示时分秒${today?time} 显示日期时间${today?datetime} 自定义格式化 ${today?string(yyyy年MM月)} 3、内建函数c model.addAttribute(“point”, 102920122); point是数字型使用${point}会显示这个数字的值每三位使用逗号分隔。 如果不想显示为每三位分隔的数字可以使用c函数将数字型转成字符串输出 ${point?c} 4、将json字符串转成对象 一个例子 其中用到了 assign标签assign的作用是定义一个变量。 #assign text{bank:工商银行,account:10101920201920212} / #assign datatext?eval / 开户行${data.bank} 账号${data.account}模板代码 !DOCTYPE html html headmeta charsetutf-8titleinner Function/title /head bodyb获得集合大小/bbr集合大小hrb获得日期/bbr显示年月日: br显示时分秒br显示日期时间br自定义格式化 brhrb内建函数C/bbr没有C函数显示的数值 br有C函数显示的数值hrb声明变量assign/bbrhr /body /html内建函数模板页面 !DOCTYPE html html headmeta charsetutf-8titleinner Function/title /head bodyb获得集合大小/bbr集合大小${stus?size}hrb获得日期/bbr显示年月日: ${today?date} br显示时分秒${today?time}br显示日期时间${today?datetime}br自定义格式化 ${today?string(yyyy年MM月)}brhrb内建函数C/bbr没有C函数显示的数值${point} br有C函数显示的数值${point?c}hrb声明变量assign/bbr#assign text{bank:工商银行,account:10101920201920212} /#assign datatext?eval /开户行${data.bank} 账号${data.account}hr /body /html内建函数Controller数据模型 GetMapping(innerFunc) public String testInnerFunc(Model model) {//1.1 小强对象模型数据Student stu1 new Student();stu1.setName(小强);stu1.setAge(18);stu1.setMoney(1000.86f);stu1.setBirthday(new Date());//1.2 小红对象模型数据Student stu2 new Student();stu2.setName(小红);stu2.setMoney(200.1f);stu2.setAge(19);//1.3 将两个对象模型数据存放到List集合中ListStudent stus new ArrayList();stus.add(stu1);stus.add(stu2);model.addAttribute(stus, stus);// 2.1 添加日期Date date new Date();model.addAttribute(today, date);// 3.1 添加数值model.addAttribute(point, 102920122);return 04-innerFunc; }2.4) 静态化测试 之前的测试都是SpringMVC将Freemarker作为视图解析器ViewReporter来集成到项目中工作中有的时候需要使用Freemarker原生Api来生成静态内容下面一起来学习下原生Api生成文本文件。 2.4.1) 需求分析 使用freemarker原生Api将页面生成html文件本节测试html文件生成的方法 2.4.2) 静态化测试 根据模板文件生成html文件 ①修改application.yml文件添加以下模板存放位置的配置信息完整配置如下 server:port: 8881 #服务端口 spring:application:name: freemarker-demo #指定服务名freemarker:cache: false #关闭模板缓存方便测试settings:template_update_delay: 0 #检查模板更新延迟时间设置为0表示立即检查如果时间大于0会有缓存不方便进行模板测试suffix: .ftl #指定Freemarker模板文件的后缀名template-loader-path: classpath:/templates #模板存放位置②在test下创建测试类 package com.heima.freemarker.test;import com.heima.freemarker.FreemarkerDemoApplication; import com.heima.freemarker.entity.Student; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;import java.io.FileWriter; import java.io.IOException; import java.util.*;SpringBootTest(classes FreemarkerDemoApplication.class) RunWith(SpringRunner.class) public class FreemarkerTest {Autowiredprivate Configuration configuration;Testpublic void test() throws IOException, TemplateException {//freemarker的模板对象获取模板Template template configuration.getTemplate(02-list.ftl);Map params getData();//合成//第一个参数 数据模型//第二个参数 输出流template.process(params, new FileWriter(d:/list.html));}private Map getData() {MapString, Object map new HashMap();//小强对象模型数据Student stu1 new Student();stu1.setName(小强);stu1.setAge(18);stu1.setMoney(1000.86f);stu1.setBirthday(new Date());//小红对象模型数据Student stu2 new Student();stu2.setName(小红);stu2.setMoney(200.1f);stu2.setAge(19);//将两个对象模型数据存放到List集合中ListStudent stus new ArrayList();stus.add(stu1);stus.add(stu2);//向map中存放List集合数据map.put(stus, stus);//创建Map数据HashMapString, Student stuMap new HashMap();stuMap.put(stu1, stu1);stuMap.put(stu2, stu2);//向map中存放Map数据map.put(stuMap, stuMap);//返回Mapreturn map;} }3) 对象存储服务MinIO 3.1 MinIO简介 MinIO基于Apache License v2.0开源协议的对象存储服务可以做为云存储的解决方案用来保存海量的图片视频文档。由于采用Golang实现服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单基本是复制可执行程序单行命令可以运行起来。 MinIO兼容亚马逊S3云存储服务接口非常适合于存储大容量非结构化的数据例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等而一个对象文件可以是任意大小从几kb到最大5T不等。 S3 Simple Storage Service简单存储服务 基本概念 bucket – 类比于文件系统的目录Object – 类比文件系统的文件Keys – 类比文件名 官网文档http://docs.minio.org.cn/docs/ 3.2 MinIO特点 数据保护 Minio使用Minio Erasure Code纠删码来防止硬件故障。即便损坏一半以上的driver但是仍然可以从中恢复。 高性能 作为高性能对象存储在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率 可扩容 不同MinIO集群可以组成联邦并形成一个全局的命名空间并跨越多个数据中心 SDK支持 基于Minio轻量的特点它得到类似Java、Python或Go等语言的sdk支持 有操作页面 面向用户友好的简单操作界面非常方便的管理Bucket及里面的文件资源 功能简单 这一设计原则让MinIO不容易出错、更快启动 丰富的API 支持文件资源的分享连接及分享链接的过期策略、存储桶操作、文件列表访问及文件上传下载的基本功能等。 文件变化主动通知 存储桶Bucket如果发生改变,比如上传对象和删除对象可以使用存储桶事件通知机制进行监控并通过以下方式发布出去:AMQP、MQTT、Elasticsearch、Redis、NATS、MySQL、Kafka、Webhooks等。 3.3 开箱使用 3.3.1 安装启动 我们提供的镜像中已经有minio的环境 我们可以使用docker进行环境部署和启动 docker run -p 9000:9000 --name minio -d --restartalways -e MINIO_ACCESS_KEYminio -e MINIO_SECRET_KEYminio123 -v /home/data:/data -v /home/config:/root/.minio minio/minio server /data3.3.2 管理控制台 假设我们的服务器地址为http://192.168.200.130:9000我们在地址栏输入http://http://192.168.200.130:9000/ 即可进入登录界面。 Access Key为minio Secret_key 为minio123 进入系统后可以看到主界面 点击右下角的“”号 点击下面的图标创建一个桶 3.4 快速入门 3.4.1 创建工程导入pom依赖 创建minio-demo,对应pom如下 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdheima-leadnews-test/artifactIdgroupIdcom.heima/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdminio-demo/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion7.1.0/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependency/dependencies/project引导类 package com.heima.minio;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class MinIOApplication {public static void main(String[] args) {SpringApplication.run(MinIOApplication.class,args);} }创建测试类上传html文件 package com.heima.minio.test;import io.minio.MinioClient; import io.minio.PutObjectArgs;import java.io.FileInputStream;public class MinIOTest {public static void main(String[] args) {FileInputStream fileInputStream null;try {fileInputStream new FileInputStream(D:\\list.html);;//1.创建minio链接客户端MinioClient minioClient MinioClient.builder().credentials(minio, minio123).endpoint(http://192.168.200.130:9000).build();//2.上传PutObjectArgs putObjectArgs PutObjectArgs.builder().object(list.html)//文件名.contentType(text/html)//文件类型.bucket(leadnews)//桶名词 与minio创建的名词一致.stream(fileInputStream, fileInputStream.available(), -1) //文件流.build();minioClient.putObject(putObjectArgs);System.out.println(http://192.168.200.130:9000/leadnews/ak47.jpg);} catch (Exception ex) {ex.printStackTrace();}}}3.5 封装MinIO为starter 3.5.1 创建模块heima-file-starter 导入依赖 dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-autoconfigure/artifactId/dependencydependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion7.1.0/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-configuration-processor/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependency /dependencies3.5.2 配置类 MinIOConfigProperties package com.heima.file.config;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties;import java.io.Serializable;Data ConfigurationProperties(prefix minio) // 文件上传 配置前缀file.oss public class MinIOConfigProperties implements Serializable {private String accessKey;private String secretKey;private String bucket;private String endpoint;private String readPath; }MinIOConfig package com.heima.file.config;import com.heima.file.service.FileStorageService; import io.minio.MinioClient; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Data Configuration EnableConfigurationProperties({MinIOConfigProperties.class}) //当引入FileStorageService接口时 ConditionalOnClass(FileStorageService.class) public class MinIOConfig {Autowiredprivate MinIOConfigProperties minIOConfigProperties;Beanpublic MinioClient buildMinioClient(){return MinioClient.builder().credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey()).endpoint(minIOConfigProperties.getEndpoint()).build();} }3.5.3 封装操作minIO类 FileStorageService package com.heima.file.service;import java.io.InputStream;/*** author itheima*/ public interface FileStorageService {/*** 上传图片文件* param prefix 文件前缀* param filename 文件名* param inputStream 文件流* return 文件全路径*/public String uploadImgFile(String prefix, String filename,InputStream inputStream);/*** 上传html文件* param prefix 文件前缀* param filename 文件名* param inputStream 文件流* return 文件全路径*/public String uploadHtmlFile(String prefix, String filename,InputStream inputStream);/*** 删除文件* param pathUrl 文件全路径*/public void delete(String pathUrl);/*** 下载文件* param pathUrl 文件全路径* return**/public byte[] downLoadFile(String pathUrl);}MinIOFileStorageService package com.heima.file.service.impl;import com.heima.file.config.MinIOConfig; import com.heima.file.config.MinIOConfigProperties; import com.heima.file.service.FileStorageService; import io.minio.GetObjectArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Import; import org.springframework.util.StringUtils;import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date;Slf4j EnableConfigurationProperties(MinIOConfigProperties.class) Import(MinIOConfig.class) public class MinIOFileStorageService implements FileStorageService {Autowiredprivate MinioClient minioClient;Autowiredprivate MinIOConfigProperties minIOConfigProperties;private final static String separator /;/*** param dirPath* param filename yyyy/mm/dd/file.jpg* return*/public String builderFilePath(String dirPath,String filename) {StringBuilder stringBuilder new StringBuilder(50);if(!StringUtils.isEmpty(dirPath)){stringBuilder.append(dirPath).append(separator);}SimpleDateFormat sdf new SimpleDateFormat(yyyy/MM/dd);String todayStr sdf.format(new Date());stringBuilder.append(todayStr).append(separator);stringBuilder.append(filename);return stringBuilder.toString();}/*** 上传图片文件* param prefix 文件前缀* param filename 文件名* param inputStream 文件流* return 文件全路径*/Overridepublic String uploadImgFile(String prefix, String filename,InputStream inputStream) {String filePath builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs PutObjectArgs.builder().object(filePath).contentType(image/jpg).bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separatorminIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();}catch (Exception ex){log.error(minio put file error.,ex);throw new RuntimeException(上传文件失败);}}/*** 上传html文件* param prefix 文件前缀* param filename 文件名* param inputStream 文件流* return 文件全路径*/Overridepublic String uploadHtmlFile(String prefix, String filename,InputStream inputStream) {String filePath builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs PutObjectArgs.builder().object(filePath).contentType(text/html).bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separatorminIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();}catch (Exception ex){log.error(minio put file error.,ex);ex.printStackTrace();throw new RuntimeException(上传文件失败);}}/*** 删除文件* param pathUrl 文件全路径*/Overridepublic void delete(String pathUrl) {String key pathUrl.replace(minIOConfigProperties.getEndpoint()/,);int index key.indexOf(separator);String bucket key.substring(0,index);String filePath key.substring(index1);// 删除ObjectsRemoveObjectArgs removeObjectArgs RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();try {minioClient.removeObject(removeObjectArgs);} catch (Exception e) {log.error(minio remove file error. pathUrl:{},pathUrl);e.printStackTrace();}}/*** 下载文件* param pathUrl 文件全路径* return 文件流**/Overridepublic byte[] downLoadFile(String pathUrl) {String key pathUrl.replace(minIOConfigProperties.getEndpoint()/,);int index key.indexOf(separator);String bucket key.substring(0,index);String filePath key.substring(index1);InputStream inputStream null;try {inputStream minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());} catch (Exception e) {log.error(minio down file error. pathUrl:{},pathUrl);e.printStackTrace();}ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();byte[] buff new byte[100];int rc 0;while (true) {try {if (!((rc inputStream.read(buff, 0, 100)) 0)) break;} catch (IOException e) {e.printStackTrace();}byteArrayOutputStream.write(buff, 0, rc);}return byteArrayOutputStream.toByteArray();} }3.5.4 对外加入自动配置 在resources中新建META-INF/spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration\com.heima.file.service.impl.MinIOFileStorageService3.5.5 其他微服务使用 第一导入heima-file-starter的依赖 第二在微服务中添加minio所需要的配置 minio:accessKey: miniosecretKey: minio123bucket: leadnewsendpoint: http://192.168.200.130:9000readPath: http://192.168.200.130:9000第三在对应使用的业务类中注入FileStorageService样例如下 package com.heima.minio.test;import com.heima.file.service.FileStorageService; import com.heima.minio.MinioApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;import java.io.FileInputStream; import java.io.FileNotFoundException;SpringBootTest(classes MinioApplication.class) RunWith(SpringRunner.class) public class MinioTest {Autowiredprivate FileStorageService fileStorageService;Testpublic void testUpdateImgFile() {try {FileInputStream fileInputStream new FileInputStream(E:\\tmp\\ak47.jpg);String filePath fileStorageService.uploadImgFile(, ak47.jpg, fileInputStream);System.out.println(filePath);} catch (FileNotFoundException e) {e.printStackTrace();}} }4)文章详情 4.1)需求分析 4.2)实现方案 方案一 用户某一条文章根据文章的id去查询文章内容表返回渲染页面 方案二 4.3)实现步骤 1.在artile微服务中添加MinIO和freemarker的支持参考测试项目 2.资料中找到模板文件article.ftl拷贝到article微服务下 3.资料中找到index.js和index.css两个文件手动上传到MinIO中 4.在文章微服务中导入依赖 dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-freemarker/artifactId/dependencydependencygroupIdcom.heima/groupIdartifactIdheima-file-starter/artifactIdversion1.0-SNAPSHOT/version/dependency /dependencies5.新建ApArticleContentMapper package com.heima.article.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.heima.model.article.pojos.ApArticleContent; import org.apache.ibatis.annotations.Mapper;Mapper public interface ApArticleContentMapper extends BaseMapperApArticleContent { }6.在artile微服务中新增测试类后期新增文章的时候创建详情静态页目前暂时手动生成 package com.heima.article.test;import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.heima.article.ArticleApplication; import com.heima.article.mapper.ApArticleContentMapper; import com.heima.article.mapper.ApArticleMapper; import com.heima.file.service.FileStorageService; import com.heima.model.article.pojos.ApArticle; import com.heima.model.article.pojos.ApArticleContent; import freemarker.template.Configuration; import freemarker.template.Template; import org.apache.commons.lang3.StringUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import java.util.HashMap; import java.util.Map;SpringBootTest(classes ArticleApplication.class) RunWith(SpringRunner.class) public class ArticleFreemarkerTest {Autowiredprivate Configuration configuration;Autowiredprivate FileStorageService fileStorageService;Autowiredprivate ApArticleMapper apArticleMapper;Autowiredprivate ApArticleContentMapper apArticleContentMapper;Testpublic void createStaticUrlTest() throws Exception {//1.获取文章内容ApArticleContent apArticleContent apArticleContentMapper.selectOne(Wrappers.ApArticleContentlambdaQuery().eq(ApArticleContent::getArticleId, 1390536764510310401L));if(apArticleContent ! null StringUtils.isNotBlank(apArticleContent.getContent())){//2.文章内容通过freemarker生成html文件StringWriter out new StringWriter();Template template configuration.getTemplate(article.ftl);MapString, Object params new HashMap();params.put(content, JSONArray.parseArray(apArticleContent.getContent()));template.process(params, out);InputStream is new ByteArrayInputStream(out.toString().getBytes());//3.把html文件上传到minio中String path fileStorageService.uploadHtmlFile(, apArticleContent.getArticleId() .html, is);//4.修改ap_article表保存static_url字段ApArticle article new ApArticle();article.setId(apArticleContent.getArticleId());article.setStaticUrl(path);apArticleMapper.updateById(article);}} }tentMapper; import com.heima.article.mapper.ApArticleMapper; import com.heima.file.service.FileStorageService; import com.heima.model.article.pojos.ApArticle; import com.heima.model.article.pojos.ApArticleContent; import freemarker.template.Configuration; import freemarker.template.Template; import org.apache.commons.lang3.StringUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; SpringBootTest(classes ArticleApplication.class) RunWith(SpringRunner.class) public class ArticleFreemarkerTest { Autowired private Configuration configuration;Autowired private FileStorageService fileStorageService;Autowired private ApArticleMapper apArticleMapper;Autowired private ApArticleContentMapper apArticleContentMapper;Test public void createStaticUrlTest() throws Exception {//1.获取文章内容ApArticleContent apArticleContent apArticleContentMapper.selectOne(Wrappers.ApArticleContentlambdaQuery().eq(ApArticleContent::getArticleId, 1390536764510310401L));if(apArticleContent ! null StringUtils.isNotBlank(apArticleContent.getContent())){//2.文章内容通过freemarker生成html文件StringWriter out new StringWriter();Template template configuration.getTemplate(article.ftl);MapString, Object params new HashMap();params.put(content, JSONArray.parseArray(apArticleContent.getContent()));template.process(params, out);InputStream is new ByteArrayInputStream(out.toString().getBytes());//3.把html文件上传到minio中String path fileStorageService.uploadHtmlFile(, apArticleContent.getArticleId() .html, is);//4.修改ap_article表保存static_url字段ApArticle article new ApArticle();article.setId(apArticleContent.getArticleId());article.setStaticUrl(path);apArticleMapper.updateById(article);} }}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

做企业网站收费多少钱apache网站拒绝访问

# 营救 ## 题目背景 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动得热泪盈眶,开起了门…… ## 题目描述 妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车&#…

网站收录量下降中国传媒大学声明

WPF(Windows Presentation Foundation)是一个用于构建桌面应用程序的.NET框架,它支持MVVM(Model-View-ViewModel)架构模式来分离UI逻辑和业务逻辑。以下是一些常用的WPF MVVM开源框架: Prism Prism是由微软…

怎么样可以自己做网站做美食直播哪个网站好

1. 介绍 概念&#xff1a;通过 ref标识 获取真实的 dom对象或者组件实例对象 2. 基本使用 实现步骤&#xff1a; 调用ref函数生成一个ref对象 通过ref标识绑定ref对象到标签 代码如下&#xff1a; 父组件&#xff1a; <script setup> import { onMounted, ref } …

汝阳县建设局网站中企动力为何负面评价那么多

关键字驱动框架&#xff1a;将每一条测试用例分成四个不同的部分 测试步骤&#xff08;Test Step&#xff09;&#xff1a;一个测试步骤的描述或者是测试对象的一个操作说明测试步骤中的对象&#xff08;Test Object&#xff09;&#xff1a;指页面的对象或者元素对象执行的动…

给网站做rss盐城市城南新区建设局网站

GOLANG专栏 Golang基础教程 Golang基础教程 Golang练手算法 Golang练手算法 Golang设计模式 Golang设计模式 Golang数据结构和算法 Golang数据结构和算法 Golang并发编程 Golang并发编程 ORM框架Gorm Golang ORM框架gorm Golang源码分析 Golang源码分析 MySQL教程 MySQ…

网站建设规划书感受网页打不开怎么解决手机

1实现步骤以及说明 1.根据参数获取当前setNoIndex表里现在的No的index值&#xff0c;如果包含关键字当前对应数据&#xff0c;则现在SetIndexNoLeft 表中找到有无未使用并未占用的那条数据&#xff08;被占用的数据IsTaken1&#xff0c;生成后使用当前时间与updated时间进行比…

智能模板网站建设收费wordpress分类页获取分类名称

华为云云耀云服务器L实例评测&#xff5c;云耀云服务器L实例部署Linux管理面板mdserver-webl 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、mdserver-web介绍2.1 mdserver-web简介2.2 mdserver-web特点2.3 主要插件介绍 三、本次实践介绍…

故城县网站建设服务汕头网站排名优化报价

函数对象 一种提供有函数调用运算符的类。 当编译器遇到了一个函数调用&#xff0c;比如lt(ival);,lt可能是个函数名、函数指针、提供了函数调用运算符的的函数对象&#xff1b; 如果lt是个类对象&#xff0c;那么编译器会在内部将此语句转换为lt.operator(ival); 函数调用运…

教用vs2013做网站的书微信小程序怎么做表格

112路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点 是…

建设网站兼职潍坊网站建设报价

1.FloatingActionButton 死活都不是圆形 必须加上下面这个属性才是圆形 app:shapeAppearance"style/ShapeAppearanceOverlay.Material3.Button"2.FloatingActionButton 中间的icon不居中 加上下面的属性&#xff0c;然后大小跟你的控件大小一致 app:fabCustomSiz…

赤峰做企业网站公司黄页网址大全免费观看直播app

最近做一个算法的GPU加速&#xff0c;发现实际上使用gcc的-O3(最高级编译优化)选项&#xff0c;可以获得很高的加速比&#xff0c;我的程序里达到了3倍的样子&#xff0c;有时效果甚至比GPU加速好。因此小小学习了下GNU的编译优化。 附言一句&#xff0c;在进行调试的时候&…

兖州网站制作定州市建设工程信息网

文章目录① 安装oracle服务端②安装plsql③配置监听④配置2个⑤重启plsql① 安装oracle服务端 ②安装plsql ③配置监听 ④配置2个 【打开客户端】-【取消】-【工具】-【首选项】-【连接】 配置截图2个配置 【Tools】-【Preferences】-【Connection】 根据自己的oracle安装路…

用wix做网站需要备案吗中国制造网平台

大模型正缓慢地渗透进入我们的生活&#xff0c;尽管目前还没有现象级的产品应用&#xff0c;但它已足以让我痴迷于它&#xff0c;我对它能够提升程序员的生产效率笃定无疑。 本次我用一个下午做了一次尝试&#xff0c;使用大模型帮助我开发一个谷歌插件。开发之前&#xff0c;…

diy网站建设源码ppt哪个网站质量高

在现代商业环境中&#xff0c;迅速而高效的沟通是企业成功的关键要素之一。而在传统的会议模式下&#xff0c;时间成本和地理限制往往给企业带来不小的困扰。针对这一问题&#xff0c;WorkPlus推出了一款创新的局域网会议软件——WorkPlus Meet&#xff0c;旨在为企业创造高效的…

网页无法打开seo到底是做什么的

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 C#在写一个实体类时&#xff0c;有属性的写法&#xff0c;省去了写getter和setter的麻烦。 在Java编程时&#xff0c;写完字段后&#x…

投放广告网站中国域名后缀

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 文章目录1. 触发器概述2. 触发器的创建3. 查看、删除触发器4.…

网站及微站建设合同验收网站开发word

在学习二叉树之前.必须先要掌握一些树的重要概念: 结点的度:一个结点含有的子树个数称为该结点的度.树的度:一棵树中,所有节点度的最大值称为树的度.叶子结点:度为0的结点称为叶子节点.(也叫终端结点)双亲结点:若一个结点含有子结点,则这个结点称为其子结点的双亲结点(也叫父节…

直播间网站开发设计wordpress 一键转微信

1、进入虚拟化vcenter中&#xff0c;用浏览器登录(客户端没找到地方设置)&#xff0c;新建一个只读用户zabbix。2、 登录vcenter客户端,将新建用户授权为只读授权过后可以使用新账号登录测试一下。3、开启exsi主机Managed Object Browser (MOB)功能&#xff0c;没有就默认开着的…

网站cc攻击用什么来做莆田网站建设推广

简介 Sanic 是一个和类Flask 的基于Python3.5的web框架&#xff0c;它编写的代码速度特别快。 除了像Flask 以外&#xff0c;Sanic 还支持以异步请求的方式处理请求。这意味着你可以使用新的 async/await 语法&#xff0c;编写非阻塞的快速的代码。 关于 asyncio 包的介绍&…