知识点一:freemarker结合MinIO生成HTML文件
- 流程:通过文章id查询到文章content表中的数据,取出content内容,并解析content内容中的json和tfl模版集合生成html,最后将生成的html上传到minio中,并返回minio中的访问地址。将地址存储在ap_article表中的static_url字段中
- 实现
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 {@AutowiredConfiguration configurable;@AutowiredFileStorageService fileStorageService;@Autowiredprivate ApArticleContentMapper apArticleContentMapper;@Autowiredprivate ApArticleMapper apArticleMapper;@Testpublic void test() throws TemplateException, IOException {ApArticleContent apArticleContent = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, 1302862387124125698L));if (apArticleContent !=null && StringUtils.isNotBlank(apArticleContent.getContent())) {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);ApArticle apArticle = new ApArticle();apArticle.setId(apArticleContent.getArticleId());apArticle.setStaticUrl(static_url);apArticleMapper.updateById(apArticle);}System.out.println("a");}
}

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

- 步骤1从过滤器中将token中取出来的id存入到header中
Object id = claimsBody.get("id");ServerHttpRequest id1 = request.mutate().headers(headers -> headers.add("id", id.toString())).build();exchange.mutate().request(id1).build();
- 将header内容放入到threadLoad中
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();}
}
- 建立拦截器
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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String userId = request.getHeader("userId");if (userId !=null) {WmUser wmUser = new WmUser();wmUser.setId(Integer.valueOf(userId));WmThreadLoadUtil.addWmUser(wmUser);}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {WmThreadLoadUtil.removeWmUser();}}
- 建立拦截器配置类
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 {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new WmTokenInterceptor()).addPathPatterns("/**");}
}
知识点三:实现图片上传接口
- 接口信息
| 说明 |
---|
接口路径 | /api/v1/material/upload_picture |
请求方式 | POST |
参数 | MultipartFile |
响应结果 | ResponseResult |
- Controller
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 {@Autowiredprivate WmMaterialService wmMaterialService;@PostMapping("/upload_picture")public ResponseResult upLoadImg(MultipartFile multipartFile){return wmMaterialService.upLoad_image(multipartFile);}
}
- Mapper
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> {
}
- ServiceImpl
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 {@Autowiredprivate FileStorageService fileStorageService;@Overridepublic 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);}
}
- 效果图

知识点四:素材列表查询
| | **说明** |
| --- | --- |
| 接口路径 | /api/v1/material/list |
| 请求方式 | POST |
| 参数 | WmMaterialDto |
| 响应结果 | ResponseResult |
- controller
@PostMapping("/list")
public ResponseResult list(@RequestBody WmMaterialDto wmMaterialDto ){return wmMaterialService.findList(wmMaterialDto);
}
- 建立Dto
package com.heima.model.wemedia.dtos;import com.heima.model.common.dtos.PageRequestDto;
import lombok.Data;@Data
public class WmMaterialDto extends PageRequestDto {private Short isCollection;
}
- service
@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());}
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;
}

知识点五:素材列表查询
- 接口
| 说明 |
---|
接口路径 | /api/v1/news/list |
请求方式 | POST |
参数 | WmNewsPageReqDto |
响应结果 | ResponseResult |
- controller
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 {@Autowiredprivate WmChannelService wmChannelService;@GetMapping("/channels")public ResponseResult findALl(){return wmChannelService.findAll();}
}
- mapper
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 {@Autowiredprivate WmChannelService wmChannelService;@GetMapping("/channels")public ResponseResult findALl(){return wmChannelService.findAll();}
}
- pojo
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;
@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;@TableField("is_default")private Boolean isDefault;@TableField("status")private Boolean status;@TableField("ord")private Integer ord;@TableField("created_time")private Date createdTime;}
- serivceImpl
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 {@Overridepublic ResponseResult findAll() {return ResponseResult.okResult(list());}
}
- 预览

知识点六:文章列表加载
- 接口
| 说明 |
---|
接口路径 | /api/v1/news/list |
请求方式 | POST |
参数 | WmNewsPageReqDto |
响应结果 | ResponseResult |
- Controller
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 {@Autowiredprivate WmNewsService wmNewsService;@PostMapping("/list")public ResponseResult list(@RequestBody WmNewsPageReqDto wmNewsPageReqDto){return wmNewsService.findList(wmNewsPageReqDto);}
}
- Mapper
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> {
}
- ServiceImpl
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 {@Overridepublic 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;}
}
- 预览图
