首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringCloud项目阶段三:HTML文件生成以及素材文章CRUD

SpringCloud项目阶段三:HTML文件生成以及素材文章CRUD

作者头像
varin
发布2025-09-28 13:06:12
发布2025-09-28 13:06:12
9200
代码可运行
举报
文章被收录于专栏:/root/root
运行总次数:0
代码可运行

知识点一:freemarker结合MinIO生成HTML文件

  1. 流程:通过文章id查询到文章content表中的数据,取出content内容,并解析content内容中的json和tfl模版集合生成html,最后将生成的html上传到minio中,并返回minio中的访问地址。将地址存储在ap_article表中的static_url字段中
  2. 实现
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.article.test;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.Template;
import freemarker.template.TemplateException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import freemarker.template.Configuration;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@SpringBootTest(classes = ArticleApplication.class)
@RunWith(SpringRunner.class)
public class ArticleTest {

    @Autowired
    Configuration configurable;
    @Autowired
    FileStorageService fileStorageService;
    @Autowired
    private ApArticleContentMapper apArticleContentMapper;
    @Autowired
    private ApArticleMapper apArticleMapper;



    @Test
    public void test() throws TemplateException, IOException {

        // 第一步:获取到文章内容
        ApArticleContent apArticleContent = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, 1302862387124125698L));
        //判断是否有内容
        if (apArticleContent !=null && StringUtils.isNotBlank(apArticleContent.getContent())) {
            // 生成html文件

            Template template = configurable.getTemplate("article.ftl");
            Map<String, Object> map = new HashMap<>();
            map.put("content", JSONArray.parseArray(apArticleContent.getContent()));
            StringWriter stringWriter = new StringWriter();
            template.process(map,stringWriter);
            System.out.println(map.get("content"));
            // 上传
            InputStream byteArrayInputStream = new ByteArrayInputStream(stringWriter.toString().getBytes());
            String static_url = fileStorageService.uploadHtmlFile("", apArticleContent.getArticleId() + ".html", byteArrayInputStream);
            System.out.println(static_url);
            // 修改 article表
            ApArticle apArticle = new ApArticle();
            apArticle.setId(apArticleContent.getArticleId());
            apArticle.setStaticUrl(static_url);
            apArticleMapper.updateById(apArticle);


            // 存储

        }
        System.out.println("a");
    }
}

知识点二:Interceptor拦截器中使用ThreadLoad存储WmUser对象

  1. 流程
  1. 步骤1从过滤器中将token中取出来的id存入到header中
代码语言:javascript
代码运行次数:0
运行
复制
       // 获取token解析后的id
            Object id = claimsBody.get("id");
            // 存ID到header中
            ServerHttpRequest id1 = request.mutate().headers(headers -> headers.add("id", id.toString())).build();
            exchange.mutate().request(id1).build();
  1. 将header内容放入到threadLoad中
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.utils.thread;

import com.heima.model.wemedia.pojos.WmUser;

public class WmThreadLoadUtil {

    private final static ThreadLocal<WmUser> WM_USER_THREAD_LOCAL = new ThreadLocal<>();
    // 添加
    public static void addWmUser(WmUser wmUser){
        WM_USER_THREAD_LOCAL.set(wmUser);
    }
    // 获取
    public static WmUser getWmUser(){
        return WM_USER_THREAD_LOCAL.get();
    }
    //清除
    public static void removeWmUser(){
        WM_USER_THREAD_LOCAL.remove();
    }
}
  1. 建立拦截器
代码语言:javascript
代码运行次数:0
运行
复制
 package com.heima.wemedia.interceptor;

import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLoadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

@Slf4j
public class WmTokenInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       String userId = request.getHeader("userId");
        if (userId !=null) {

            // 创建一个wmUser对象并存储到threadLoad中
            WmUser wmUser = new WmUser();
            wmUser.setId(Integer.valueOf(userId));
            WmThreadLoadUtil.addWmUser(wmUser);


        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 请求结束,清除用户
        WmThreadLoadUtil.removeWmUser();
    }
    //

}
  1. 建立拦截器配置类
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.config;

import com.heima.wemedia.interceptor.WmTokenInterceptor;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WmMvcConfig implements WebMvcConfigurer {
    //添加拦截器并拦截所有
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WmTokenInterceptor())
        .addPathPatterns("/**");
    }
}

知识点三:实现图片上传接口

  1. 接口信息

说明

接口路径

/api/v1/material/upload_picture

请求方式

POST

参数

MultipartFile

响应结果

ResponseResult

  1. Controller
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.controller.v1;

import com.heima.model.common.dtos.ResponseResult;
import com.heima.wemedia.service.WmMaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/api/v1/material/")
public class WmMaterialController {
    @Autowired
    private WmMaterialService wmMaterialService;

    @PostMapping("/upload_picture")



    public ResponseResult upLoadImg(MultipartFile multipartFile){
        return wmMaterialService.upLoad_image(multipartFile);

    }
}
  1. Mapper
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.wemedia.pojos.WmMaterial;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface WmMaterialMapper extends BaseMapper<WmMaterial> {
}
  1. ServiceImpl
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.utils.thread.WmThreadLoadUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.service.WmMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.UUID;

@Service
@Transactional
@Slf4j
public class WmMaterialServiceImpl extends ServiceImpl<WmMaterialMapper, WmMaterial> implements WmMaterialService {

    @Autowired
    private FileStorageService fileStorageService;

    @Override
    public ResponseResult upLoad_image(MultipartFile multipartFile ) {

        if (multipartFile !=null &&multipartFile.getSize()!=0) {
            ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);

        }
        // 拼接名称
        String replace = UUID.randomUUID().toString().replace("-", "");

        String originalFilename = multipartFile.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 上传
        String url = "";
        try {
            url= fileStorageService.uploadImgFile("", replace + suffix, multipartFile.getInputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println(url);
        System.out.println(WmThreadLoadUtil.getWmUser());

        WmMaterial wmMaterial = new WmMaterial();
        wmMaterial.setUserId(WmThreadLoadUtil.getWmUser().getId());
        wmMaterial.setUrl(url);
        wmMaterial.setType((short)0);
        wmMaterial.setCreatedTime(new Date());
        wmMaterial.setIsCollection((short)0);
        save(wmMaterial);






        return ResponseResult.okResult(wmMaterial);
    }
}
  1. 效果图

知识点四:素材列表查询

| | **说明** | | --- | --- | | 接口路径 | /api/v1/material/list | | 请求方式 | POST | | 参数 | WmMaterialDto | | 响应结果 | ResponseResult |

  1. controller
代码语言:javascript
代码运行次数:0
运行
复制
@PostMapping("/list")
public ResponseResult list(@RequestBody WmMaterialDto wmMaterialDto ){

    return wmMaterialService.findList(wmMaterialDto);
}
  1. 建立Dto
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.model.wemedia.dtos;

import com.heima.model.common.dtos.PageRequestDto;
import lombok.Data;

@Data
public class WmMaterialDto  extends PageRequestDto {
    /**
     * 1 收藏
     * 0 未收藏
     */
    private Short isCollection;
}
  1. service
代码语言:javascript
代码运行次数:0
运行
复制
@Override
public ResponseResult findList(WmMaterialDto wmMaterialDto) {
// 检查参数
wmMaterialDto.checkParam();
//分页查询
IPage page = new Page(wmMaterialDto.getPage(),wmMaterialDto.getSize());
LambdaQueryWrapper<WmMaterial> queryWrapper = new LambdaQueryWrapper<WmMaterial>();
// 是否收藏
if (wmMaterialDto.getIsCollection() !=null && wmMaterialDto.getIsCollection()==1) {
    queryWrapper.eq(WmMaterial::getIsCollection,wmMaterialDto.getIsCollection());

}

// 按照用户id查询
queryWrapper.eq(WmMaterial::getUserId,WmThreadLoadUtil.getWmUser().getId());
// 创建时间倒序
queryWrapper.orderByDesc(WmMaterial::getCreatedTime);

page = page(page, queryWrapper);

PageResponseResult pageResponseResult = new PageResponseResult(wmMaterialDto.getPage(), wmMaterialDto.getSize(), (int) page.getTotal());
pageResponseResult.setData(page.getRecords());

return pageResponseResult;
}

知识点五:素材列表查询

  1. 接口

说明

接口路径

/api/v1/news/list

请求方式

POST

参数

WmNewsPageReqDto

响应结果

ResponseResult

  1. controller
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.controller.v1;

import com.heima.model.common.dtos.ResponseResult;
import com.heima.wemedia.service.WmChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/channel/")

public class WmChannelController {
    @Autowired
    private WmChannelService wmChannelService;

    @GetMapping("/channels")
    public ResponseResult findALl(){
        return wmChannelService.findAll();
    }
}
  1. mapper
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.controller.v1;

import com.heima.model.common.dtos.ResponseResult;
import com.heima.wemedia.service.WmChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/channel/")

public class WmChannelController {
    @Autowired
    private WmChannelService wmChannelService;

    @GetMapping("/channels")
    public ResponseResult findALl(){
        return wmChannelService.findAll();
    }
}
  1. pojo
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.model.wemedia.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("wm_channel")
public class WmChannel implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 频道名称
     */
    @TableField("name")
    private String name;

    /**
     * 频道描述
     */
    @TableField("description")
    private String description;

    /**
     * 是否默认频道
     * 1:默认     true
     * 0:非默认   false
     */
    @TableField("is_default")
    private Boolean isDefault;

    /**
     * 是否启用
     * 1:启用   true
     * 0:禁用   false
     */
    @TableField("status")
    private Boolean status;

    /**
     * 默认排序
     */
    @TableField("ord")
    private Integer ord;

    /**
     * 创建时间
     */
    @TableField("created_time")
    private Date createdTime;

}
  1. serivceImpl
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.service.WmChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@Slf4j
public class WmChannelServiceImpl   extends ServiceImpl<WmChannelMapper, WmChannel> implements WmChannelService {


    @Override
    public ResponseResult findAll() {
        return ResponseResult.okResult(list());
    }
}
  1. 预览

知识点六:文章列表加载

  1. 接口

说明

接口路径

/api/v1/news/list

请求方式

POST

参数

WmNewsPageReqDto

响应结果

ResponseResult

  1. Controller
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.controller.v1;


import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.wemedia.service.WmNewsService;
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/news")
public class WnNewsController {

    @Autowired
    private WmNewsService wmNewsService;
    @PostMapping("/list")
    public ResponseResult list(@RequestBody WmNewsPageReqDto wmNewsPageReqDto){
        return wmNewsService.findList(wmNewsPageReqDto);
    }
}
  1. Mapper
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.wemedia.pojos.WmNews;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface WnNewsMapper extends BaseMapper<WmNews> {
}
  1. ServiceImpl
代码语言:javascript
代码运行次数:0
运行
复制
package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLoadUtil;
import com.heima.wemedia.mapper.WnNewsMapper;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.util.HttpExceptionUtils;
import org.apache.hadoop.util.ThreadUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@Slf4j
public class WmNewsServiceImpl extends ServiceImpl<WnNewsMapper, WmNews> implements WmNewsService {
    @Override
    public ResponseResult findList(WmNewsPageReqDto wmNewsPageReqDto) {
        WmUser wmUser = WmThreadLoadUtil.getWmUser();
        if (wmUser==null || wmNewsPageReqDto==null) {
            return  ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }


        // 检查参数
        wmNewsPageReqDto.checkParam();

        // 分页查询
        IPage page = new Page(wmNewsPageReqDto.getPage(), wmNewsPageReqDto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<WmNews>();
        // 状态精确查询
        if (wmNewsPageReqDto.getStatus()!=null) {
            queryWrapper.eq(WmNews::getStatus,wmNewsPageReqDto.getStatus());
        }

        //频道精确查询
        if (wmNewsPageReqDto.getChannelId() !=null) {
            queryWrapper.eq(WmNews::getChannelId,wmNewsPageReqDto.getChannelId());
        }

        // 发布时间模糊查询

        if (wmNewsPageReqDto.getBeginPubDate()!=null && wmNewsPageReqDto.getEndPubDate()!=null) {
            queryWrapper.between(WmNews::getPublishTime,wmNewsPageReqDto.getBeginPubDate(),wmNewsPageReqDto.getEndPubDate());
        }
        // 关键字模糊查询
        if (wmNewsPageReqDto.getKeyword() !=null) {

            queryWrapper.like(WmNews::getTitle,wmNewsPageReqDto.getKeyword());
        }
        // 当前用户登录查询
        queryWrapper.eq(WmNews::getUserId, WmThreadLoadUtil.getWmUser().getId());
        //发布时间倒序
        queryWrapper.orderByDesc(WmNews::getPublishTime);

        page = page(page, queryWrapper);
        ResponseResult responseResult = new PageResponseResult(wmNewsPageReqDto.getPage(),wmNewsPageReqDto.getSize(),(int)page.getTotal());
        responseResult.setData(page.getRecords());
        return responseResult;
    }
}
  1. 预览图
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-09-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 知识点一:freemarker结合MinIO生成HTML文件
  • 知识点二:Interceptor拦截器中使用ThreadLoad存储WmUser对象
  • 知识点三:实现图片上传接口
  • 知识点四:素材列表查询
  • 知识点五:素材列表查询
  • 知识点六:文章列表加载
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档