SpringBoot项目实战(41)--Beetl网页使用自定义函数获取新闻列表

        在Beetl页面中可以使用自定义的函数从后台新闻列表中获取新闻数据展示到页面上。例如我们可以从后台新闻表中获取新闻按照下面的格式展示:

 <li><a href="#">东亚非遗展即将盛妆亮相 揭起盖头先睹为快</a></li>
 <li><a href="#">上海之春国际音乐节启幕在即 凸显“一带一路”时代主题</a></li>

   使用Beetl自定义函数时,我们需要在后台实现一个类,继承Beetl的Function,见下面的代码:

package org.openjweb.core.service;
 
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.Context;
import org.beetl.core.Function;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class BeetlService implements Function {

    public List<Map<String,Object>> getCateInfoListDemo(String treeCode ){

        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        map.put("infTitle","国庆节来了"+treeCode);
        map.put("infUrl","http://www.sohu.com");
        map.put("Image","");
        list.add(map);
        map = new HashMap<>();
        map.put("infTitle","2025年春节放假通知"+treeCode);
        map.put("infUrl","http://www.sohu.com");
        map.put("Image","");
        list.add(map);
        return list;
    }

    @Override
    public Object call(Object[] objects, Context context) {

        if(objects.length>1){
            log.info("第二个参数pageNo:"+String.valueOf(objects[1]));

        }
        if(objects.length>2){
            log.info("第三个参数pageSize:"+String.valueOf(objects[2]));

        }
        if(1==2) {

            return this.getCateInfoListDemo((String )objects[0]);
        }
        else {
            log.info("传入的栏目编码为:::::");
            log.info(String.valueOf(objects[0]));

            return this.getCateInfoList((String) objects[0], 1, 10);
        }

    }
    public Object getCateInfoList(String treeCode ,int pageNo,int pageSize){
        HttpRequest request = HttpRequest.get("http://localhost:8001/api/cms/pub/getCateInfoList?treeCode="+treeCode+"&pageNo="+pageNo+"&pageSize="+pageSize);
        HttpResponse response = request.execute();
        String result = response.body();
        log.info("请求返回的内容:");
        log.info(result);
        return JSONArray.parseArray(result) ;
    }


}

        在上面的代码中,call方法接收Beetl网页前端传入的参数,参数分别是栏目编码、页面、每页行数,然后调用this.getCateInfoListDemo((String )objects[0]); 这个是个简单的示例,封装了2条Map数据返回给前端页面。

        另外需要在以前的BeetlConf中注册函数,我们就把BeetlService类作为一个函数,下面是BeetlConf的代码:

package org.openjweb.core.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.core.resource.FileResourceLoader;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.beetl.ext.spring.BeetlSpringViewResolver;
import org.openjweb.core.service.BeetlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.WebApplicationContext;

@Configuration
@Slf4j
public class BeetlConf {

    @Autowired
    private WebApplicationContext wac;

    //@Value("${beetl.templatesPath}") String templatesPath;//模板根目录 ,比如 "templates"
    String templatesPath = "templates";//这个给类定义使用的
    @Value("${beetl.fileTemplatesPath:}") String fileTemplatesPath;//模板根目录 ,比如 "templates"
    String templateFilePath = "";
    @Bean(name = "beetlConfig")
    public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() {
        BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
        //获取Spring Boot 的ClassLoader
        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        if(loader==null){
            loader = BeetlConf.class.getClassLoader();
        }
        //log.info("当前指定的Beetl模板文件路径:"+String.valueOf(fileTemplatesPath));
        //beetlGroupUtilConfiguration.setConfigProperties(extProperties);//额外的配置,可以覆盖默认配置,一般不需要

        if(StringUtils.isNotEmpty(fileTemplatesPath)){
            log.info("使用文件模版路径...........");
            FileResourceLoader floader = new FileResourceLoader(fileTemplatesPath);
            beetlGroupUtilConfiguration.setResourceLoader(floader);
        }
        else{
            log.info("使用类模版路径...........");
            ClasspathResourceLoader cploder = new ClasspathResourceLoader(loader,  templatesPath);
            beetlGroupUtilConfiguration.setResourceLoader(cploder);
        }

        beetlGroupUtilConfiguration.init();


        //如果使用了优化编译器,涉及到字节码操作,需要添加ClassLoader
        beetlGroupUtilConfiguration.getGroupTemplate().setClassLoader(loader);

        //注册国际化函数
        beetlGroupUtilConfiguration.getGroupTemplate().registerFunction("i18n", new I18nFunction(wac));
        //注册cms相关的方法
        beetlGroupUtilConfiguration.getGroupTemplate().registerFunction("cmsUtil",new BeetlService());

        return beetlGroupUtilConfiguration;

    }

    @Bean(name = "beetlViewResolver")
    public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
        BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
        beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
        beetlSpringViewResolver.setOrder(0);
        beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
        return beetlSpringViewResolver;
    }


}

        注意在上面的代码中,将BeetlService注册为一个名为cmsUtil 的函数:

 beetlGroupUtilConfiguration.getGroupTemplate().registerFunction("cmsUtil",new BeetlService());

    然后在前端页面(D:\tmp\beetl\templates\cms\site\wenhua\china.html)中,使用下面的代码来调用后台BeetlService函数(此函数传入3个参数,在后台的call方法中通过Object[]参数接收):

<%
    for(item in cmsUtil("001001",1,10)){
%>
    <li><a href="${item.infUrl}">${item.infTitle}</a></li>
<% 
    }
%>

测试: http://localhost:8001/front/china

显示效果,在界面上显示了BeetlService中的演示数据:

另外如果调用后台新闻表cms_info的新闻,在BeetlService中使用了

public Object getCateInfoList(String treeCode ,int pageNo,int pageSize){
        HttpRequest request = HttpRequest.get("http://localhost:8001/api/cms/pub/getCateInfoList?treeCode="+treeCode+"&pageNo="+pageNo+"&pageSize="+pageSize);
        HttpResponse response = request.execute();
        String result = response.body();
        log.info("请求返回的内容:");
        log.info(result);
        return JSONArray.parseArray(result) ;
    }

因为在OpenJweb工程中,openjweb-cms内容管理模块是依赖openjweb-core模块,所以在openjweb-core模块里的BeetlService中,如果调用CMS的API方法,不能直接引用openjweb-cms的Service类,只能通过Http的方式调用openjweb-cms里的API接口(/api/cms/pub/getCateInfoList

),这里通过Hutool进行了get调用。下面是CmsInfoV3Api的获取栏目信息接口代码:

package org.openjweb.cms.api;

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.openjweb.cms.entity.CmsInfo;
import org.openjweb.cms.module.params.CmsInfoParam;
import org.openjweb.cms.service.CmsInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Api(tags = "内容管理V3")
@Slf4j
@RestController
@RequestMapping("/api/cms/pub")
public class CmsInfoV3Api {

    @Autowired
    private CmsInfoService cmsInfoService;

    @RequestMapping("/getCateInfoList")
    public List<CmsInfo> getCateCmsInfo(String treeCode, int pageNo, int pageSize){
        log.info("getCateInfoList传入的参数:");
        log.info(treeCode);
        log.info(String.valueOf(pageNo));
        log.info(String.valueOf(pageSize));

        CmsInfoParam param = new CmsInfoParam();
        param.setPage(pageNo);
        param.setPageSize(pageSize);
        param.setCateTreeCode(treeCode);
        List<CmsInfo> list = this.cmsInfoService.queryList(param);
        if(list!=null&&list.size()>0){
            //${myService.sayHello('World')}
            log.info("查询到栏目的信息......");
        }
        else{
            log.info("没查到栏目下的信息.....");
        }
        return list;
        //List<CmsInfo> cmsInfo



    }
}

在SpringSecurity中,配置/api/cms/pub为免登录可以访问。我们在BeetlService中改为调用这个接口:

if(1==2) {
    return this.getCateInfoListDemo((String )objects[0]);
}
else {
    log.info("传入的栏目编码为:::::");
    log.info(String.valueOf(objects[0]));
    return this.getCateInfoList((String) objects[0], 1, 10);
}

上面的代码调用this.getCateInfoList,然后重新运行SpringBoot,访问http://localhost:8001/front/china:

上面是从cms_info表获取的新闻列表的标题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LayaAir3.2来了:性能大幅提升、一键发布安装包、支持WebGPU、3D导航寻路、升级为真正的全平台引擎

前言 LayaAir3的每一个分支版本都是一次较大的提升&#xff0c;在3.1彻底完善了引擎生态结构之后&#xff0c;本次的3.2会重点完善全平台发布相关的种种能力&#xff0c;例如&#xff0c;除原有的安卓与iOS系统外&#xff0c;还支持Windows系统、Linux系统、鸿蒙Next系统&#…

【力扣热题100】—— Day18.将有序数组转换为二叉搜索树

期末考试完毕&#xff0c;假期学习开始&#xff01; —— 25.1.7 108. 将有序数组转换为二叉搜索树 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵平衡二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] …

C++ Qt练习项目 QChar功能测试

个人学习笔记 代码仓库 GitCode - 全球开发者的开源社区,开源代码托管平台 新建项目 设计UI 1、拖入group box去掉名字 2、拖入2个LineEdit 3、拖入两个Label 4、拖入两个PushButton 5、点栅格布局 1、拖入GroupBox 2、拖入4个PushButton 3、点栅格布局 1、拖入GroupBo…

保证Mysql数据库到ES的数据一致性的解决方案

文章目录 1.业务场景介绍1.1 需求分析1.2 技术实现方案 2.业界常用数据一致性方案分析2.1 同步双写方案2.2 MQ异步双写方案2.3 扫表定期同步方案2.4 监听binlog同步方案 1.业务场景介绍 1.1 需求分析 某知名的在线旅游平台&#xff0c;在即将到来的春季促销活动之前&#xff…

初学stm32 --- DAC模数转换器工作原理

目录 什么是DAC&#xff1f; DAC的特性参数 STM32各系列DAC的主要特性 DAC框图简介&#xff08;F1/F4/F7&#xff09; 参考电压/模拟部分电压 触发源 关闭触发时(TEN0)的转换时序图 DMA请求 DAC输出电压 什么是DAC&#xff1f; DAC&#xff0c;全称&#xff1a;Digital…

《HTTP协议与内外网划分:网络世界的基石知识》

http协议与内外网的划分 http协议的简介 HTTP&#xff08;超文本传输协议&#xff09;是互联网上应用最广泛的一种网络协议&#xff0c;用于从服务器传输超文本&#xff08;如HTML&#xff09;到本地浏览器的传输协议。以下是关于HTTP协议的简介&#xff1a; HTTP协议的基本…

二叉树层序遍历 Leetcode102.二叉树的层序遍历

二叉树的层序遍历相当于图论的广度优先搜索&#xff0c;用队列来实现 &#xff08;二叉树的递归遍历相当于图论的深度优先搜索&#xff09; 102.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右…

特制一个自己的UI库,只用CSS、图标、emoji图 第二版

图&#xff1a; 代码&#xff1a; index.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>M…

12工具篇(D3_Lombok)

目录 一、基本介绍 二、Lombok使用说明 1. 基本介绍 2. 安装插件 IDEA在线安装Lombok插件 IDEA离线安装Lombok插件 3. 引入依赖坐标 4. Lombok注解功能说明 NonNull Getter&Setter Cleanup ToString EqualsAndHashCode Constructor RequiredArgsConstructor …

STM32如何测量运行的时钟频率

前言 环境&#xff1a; 芯片&#xff1a;STM32F103C8T6 Keil&#xff1a;V5.24.2.0 一、简介STM32F103C8T6的时钟源 ①HSI 内部高速时钟,RC振荡器&#xff0c;频率为8MHz&#xff0c;精度不高。②HSE 外部高速时钟,可接石英/陶瓷谐振器&#xff0c;频率范围为4MHz~16MHz&…

【物流管理系统 - IDEAJavaSwingMySQL】基于Java实现的物流管理系统导入IDEA教程

有问题请留言或私信 步骤 下载项目源码&#xff1a;项目源码 解压项目源码到本地 打开IDEA 左上角&#xff1a;文件 → 新建 → 来自现有源代码的项目 找到解压在本地的项目源代码文件&#xff0c;点击确定&#xff0c;根据图示步骤继续导入项目 查看项目目录&#xff…

时序数据库InfluxDB—介绍与性能测试

目录 一、简述 二、主要特点 三、基本概念 1、主要概念 2、保留策略 3、连续查询 4、存储引擎—TSM Tree 5、存储目录 四、基本操作 1、Java-API操作 五、项目中的应用 六、单节点的硬件配置 七、性能测试 1、测试环境 2、测试程序 3、写入测试 4、查询测试 一…

探索数据存储的奥秘:深入理解B树与B+树

key value 类型的数据红黑树&#xff08;最优二叉树&#xff0c;内存最优&#xff09;&#xff0c;时间复杂度&#xff1a;O&#xff08;logn&#xff09;,调整方便&#xff1b;一个结点分出两个叉B树一个节点可以分出很多叉数据量相等的条件下&#xff1a;红黑树的层数很高&am…

element ui前端小数计算精度丢失的问题如何解决?

文章目录 前言一、什么是精度丢失&#xff1f;产生精度丢失的原因如何避免或减少精度丢失的影响 二、实际项目开发实例举例以项目预算模块为例如何解决精度丢失 总结 前言 在《工程投标项目管理系统》项目开发中工程项目预算、成本管理、财务管理等模块的开发中不可避免的要和…

小程序textarea组件键盘弹起会遮挡住输入框

<textarea value"{{remark}}" input"handleInputRemark" ></textarea> 如下会有遮挡&#xff1a; 一行代码搞定 cursor-spacing160 修改后代码 <textarea value"{{remark}}" input"handleInputRemark" cursor-spacin…

k8s笔记29--使用kyverno提高运维效率

k8s笔记29--使用kyverno提高运维效率 介绍原理安装应用场景自动修正测试环境pod资源强制 Pod 标签限制容器镜像来源禁止特权容器其它潜在场景 注意事项说明 介绍 Kyverno是一个云原生的策略引擎&#xff0c;它最初是为k8s构建的&#xff0c;现在也可以在k8s集群之外用作统一的…

如何理解机器学习中的线性模型 ?

在机器学习中&#xff0c;线性模型是一类重要且基础的模型&#xff0c;它假设目标变量&#xff08;输出&#xff09;是输入变量&#xff08;特征&#xff09;的线性组合。线性模型的核心思想是通过优化模型的参数&#xff0c;使模型能够捕捉输入与输出之间的线性关系。以下是线…

数据结构初阶---排序

一、排序相关概念与运用 1.排序相关概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的…

树莓派-5-GPIO的应用实验之GPIO的编码方式和SDK介绍

文章目录 1 GPIO编码方式1.1 管脚信息1.2 使用场合1.3 I2C总线1.4 SPI总线2 RPI.GPIO2.1 PWM脉冲宽度调制2.2 静态函数2.2.1 函数setmode()2.2.2 函数setup()2.2.3 函数output()2.2.4 函数input()2.2.5 捕捉引脚的电平改变2.2.5.1 函数wait_for_edge()2.2.5.2 函数event_detect…

学习RocketMQ

1.为什么要用MQ&#xff1f; 消息队列是一种“先进先出”的数据结构 其应用场景主要包含以下4个方面&#xff1a; 1.1 异步解耦​ 最常见的一个场景是用户注册后&#xff0c;需要发送注册邮件和短信通知&#xff0c;以告知用户注册成功。传统的做法有以下两种&#xff1a; …