一 页面中心crud
站点
页面管理
页面配置
二 feign做文件上传和下载 *****
Feign
Common
<!--客户端feign支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>2.1.0</version>
</dependency>
Page
<!-- 引入feign fastdfs调用-->
<!--所有provider公共依賴-->
<dependency>
<groupId>cn.itsource</groupId>
<artifactId>hrm-common-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
下载
Feigin
//获取用户
@RequestMapping(value = "/download",method = RequestMethod.GET,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
Response download(@RequestParam("path")String path); //直接把流写到response
Service
@GetMapping(value = "/download",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public void download(@RequestParam("path")String path, HttpServletResponse response) {
String pathTmp = path.substring(1); // goup1/xxxxx/yyyy
String groupName = pathTmp.substring(0, pathTmp.indexOf("/")); //goup1
String remotePath = pathTmp.substring(pathTmp.indexOf("/")+1);// xxxxx/yyyy
System.out.println(groupName);
System.out.println(remotePath);
OutputStream os = null;
InputStream is = null;
try {
byte[] datas = FastDfsApiOpr.download(groupName, remotePath);
os = response.getOutputStream(); //直接给以流方式进行返回
is = new ByteInputStream(datas,datas.length);
IOUtils.copy(is,os);
调用:
Response response =
fastDfsClient.download(templateUrl); //通过fastdfs下载压缩包
String tmpdir=System.getProperty("java.io.tmpdir");
System.out.println(tmpdir);
String zipName = tmpdir+"/temp.zip";
os = new FileOutputStream(zipName);
is = response.body().asInputStream();
IOUtils.copy(is , os); //保存到本地
上传:
Feign
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>2.1.0</version>
</dependency>
package cn.itsource.hrm.config;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
@Configuration
public class FeignMultipartSupportConfig {
@Bean
@Primary
@Scope("prototype")
public Encoder multipartFormEncoder() {
return new SpringFormEncoder();
}
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
}
//fallbackFactory = CourseTypeClientHystrixFallbackFactory.class
@FeignClient(value = "HRM-FASTDFS",configuration = FeignMultipartSupportConfig.class,
//@FeignClient(value = "HRM-FASTDFS",configuration = FeignClientsConfiguration.class,
fallbackFactory = FastDfsClientHystrixFallbackFactory.class
)
@RequestMapping("/fastdfs")
public interface FastDfsClient {
@PostMapping(value= "/upload", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}
, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String upload(@RequestPart(value = "file") MultipartFile file);
Service:
@PostMapping(value = "/upload", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}
, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String upload(@RequestPart(value = "file") MultipartFile file) {
调用
!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
@Autowired
private FastDfsClient fastDfsClient;
@Test
public void test1() throws Exception{
FileItem fileItem = createFileItem(new File("C:\\Users\\Administrator\\Desktop\\问题.txt"));
MultipartFile mfile = new CommonsMultipartFile(fileItem);
fastDfsClient.upload(mfile);
}
/*
创建FileItem
*/
private FileItem createFileItem(File file) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
String textFieldName = "textField";
FileItem item = factory.createItem("file", "text/plain", true, file.getName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
try {
FileInputStream fis = new FileInputStream(file);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return item;
}
三 静态化实现
1)准备模板-经过测试
2)添加页面-把准备好的模板上传上去
3)触发初始化-前端后台管理
页面-触发courseType的controller
模块:hrm-course-service-2020
Pom
<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
导入
测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CouseServiceApplication2020.class)
public class ICourseTypeServiceTest {
@Autowired
private ICourseTypeService courseTypeService;
@Test
public void testVelocityTmplate() {
//数据+模板=静态页面
Map<String,Object> model = new HashMap<>();
model.put("staticRoot","D:\\0924\\2020-02-24-hrm-课程中心-课程主站-页面静态化实现\\resources\\home");
model.put("courseTypes",courseTypeService.treeData(0L));
VelocityUtils.staticByTemplate(model,
"D:\\0924\\2020-02-24-hrm-课程中心-课程主站-页面静态化实现\\resources\\home\\home.vm",
"D:\\0924\\2020-02-24-hrm-课程中心-课程主站-页面静态化实现\\resources\\home\\home.vm"+".html");
}
4)调用页面静态化-课程服务
@Override
public void staticIndexPageInit() {
//1页面名称写死,约定大于配置
String pageName = "CourseSiteIndex";
//2 需要一个保存到redis数据库的key
String dataKey="CourseSiteIndex_data";
//本来就是从redis获取,还要在放一次,其他页面静态化的场景不一定有缓冲
List<CourseType> courseTypes = this.treeData(0L);
//课程处理
Map<String,Object> courseTypeSdata = new HashMap<>();
courseTypeSdata.put("courseTypes",courseTypes);
//职位
// Map<String,Object> JobsTypeSdata = new HashMap<>();
// JobsTypeSdata.put(“jobTypes”,courseTypes);
redisClient.add(dataKey, JSONArray.toJSONString(courseTypeSdata)); //{courseTypes:[]}
//3 调用方法模板+数据=静态页面
pageConfigClient.staticPage(pageName,dataKey);
}
5)做页面静态化-页面中心 *****
模板
数据
静态化
上传到fastdfs
保存pageConfig
发消息
PageConfigController
//页面静态化接口
@PostMapping("/staticPage")
AjaxResult staticPage(@RequestBody Map<String, String> map){
String dataKey = map.get("dataKey");
String pageName = map.get("pageName");
try {
pageConfigService.staticPage(dataKey,pageName);
return AjaxResult.me();
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("静态化失败!"+e.getMessage());
}
}
@Override
public void staticPage(String dataKey, String pageName) {
FileOutputStream os = null;
InputStream is = null;
try {
//一 页面静态化
Pager pager = pagerMapper
.selectList(new EntityWrapper<Pager>().eq("name", pageName)).get(0);
String templateUrl = pager.getTemplateUrl(); //fastdfs地址 zip包的
String templateName = pager.getTemplateName(); //要执行模板文件
//1.1 下载fastdfs上面压缩包
Response response =
fastDfsClient.download(templateUrl); //通过fastdfs下载压缩包
is = response.body().asInputStream();
//1.2 所有静态化中间数据都写入临时目录
//1)跨操作系统
//2 操作系统会自动维护,不用删除
String tmpdir=System.getProperty("java.io.tmpdir");
System.out.println(tmpdir+"jjjjj.........");
String zipPath = tmpdir+"/temp.zip"; //要下载zip包路径
String unZipPath = tmpdir + "/temp/"; //解压到路径
os = new FileOutputStream(zipPath);
IOUtils.copy(is , os); //保存到本地
ZipUtil.unzip(zipPath,unZipPath); // 解压缩
//1.3 获取到模板
String templatePath = unZipPath+"/"+templateName; //模板路径 temp/home.vm
System.out.println(templatePath+"zz.........");
//2 生成静态页面的路劲
String templatePagePath = templatePath+".html"; //本地静态页面地址
System.out.println(templatePagePath+"xxx.........");
//3 生成数据
String courseTypes =redisClient.get("courseTypes"); //redis数据
List<CourseTypeDto> courseTypeDtos = JSONArray.parseArray(courseTypes,CourseTypeDto.class);
Map<String, Object> modelMap = new HashMap<>(); //封装两个参数作为一个对象传入进去
modelMap.put("staticRoot", unZipPath);
modelMap.put("courseTypes", courseTypeDtos);
//4 做页面静态化
VelocityUtils.staticByTemplate(modelMap,templatePath,templatePagePath); //进行页面静态化
// 5 传递到fastdfs
String pageUrl = fastDfsClient.upload(
new CommonsMultipartFile(createFileItem(new File(templatePagePath),"file")));
//二 PageConfig 并且进行保存
PageConfig config = new PageConfig();
config.setTemplateUrl(templateUrl);
config.setTemplateName(templateName);
config.setDataKey(dataKey);
config.setPhysicalPath(pager.getPhysicalPath());
config.setDfsType(0L); //0表示fastDfs
config.setPageUrl(pageUrl);
config.setPageId(pager.getId());
pageConfigMapper.insert(config);
//三 往消息队列放入消息
String routingKey = siteMapper
.selectList(new EntityWrapper<Site>().eq("id", pager.getSiteId())).get(0).getSn();
System.out.println(routingKey+"ddh......");
JSONObject jsonObject = new JSONObject();
jsonObject.put("fileSysType",0);
jsonObject.put("staticPageUrl",pageUrl);
jsonObject.put("physicalPath",pager.getPhysicalPath());
System.out.println(jsonObject.toJSONString()+"dbl.....");
rabbitTemplate.convertAndSend(
RabbitmqConstants.EXCHANGE_DIRECT_INFORM,routingKey,jsonObject.toJSONString());
}catch (Exception e){
e.printStackTrace();
}finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
创建FileItem
*/
private FileItem createFileItem(File file,String filedName) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem item = factory.createItem(filedName, "text/plain", true, file.getName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
try {
FileInputStream fis = new FileInputStream(file);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return item;
}
6.3.3. 页面发布消费方 -PageAgent
package cn.itsource.hrm.config;
import org.springframework.amqp.core.*;
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;
/**
* 主站
* 课程管理
* 职位管理
*/
@Configuration
public class RabbitmqConfig {
@Value("${rabbitmq.queues.routingKey}")
public String routingKey;
public static final String EXCHANGE_DIRECT_INFORM = RabbitmqConstants.EXCHANGE_DIRECT_INFORM;
public static final String QUEUE_INFORM_PAGESTATIC = RabbitmqConstants.QUEUE_INFORM_PAGESTATIC;
/**
* 交换机配置
* ExchangeBuilder提供了fanout、direct、topic、header交换机类型的配置
*
* @return the exchange
*/
@Bean(EXCHANGE_DIRECT_INFORM)
public Exchange exchange_direct_inform() {
//durable(true)持久化,消息队列重启后交换机仍然存在
return ExchangeBuilder.directExchange(EXCHANGE_DIRECT_INFORM).durable(true).build();
}
//声明队列
@Bean(QUEUE_INFORM_PAGESTATIC) //交给spring管理的bean的名字可以随便的
public Queue pageStaticQueue() {
Queue queue = new Queue(QUEUE_INFORM_PAGESTATIC); //队列名
return queue;
}
// Qualifier//获取特定名称bean
@Bean
public Binding BINDING_QUEUE_INFORM_HRMJOBSITE(@Qualifier(QUEUE_INFORM_PAGESTATIC) Queue queue,
@Qualifier(EXCHANGE_DIRECT_INFORM) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs();
}
public String getRoutingKey() {
return routingKey;
}
public void setRoutingKey(String routingKey) {
this.routingKey = routingKey;
}
}
@Component
public class StaticPageDownloadHandler {
@Autowired
private FastDfsClient fastDfsClient;
@RabbitListener(queues = RabbitmqConstants.QUEUE_INFORM_PAGESTATIC)
public void receiveHomeSite(String msg, Message message, Channel channel) {
//msg -fileSysType,staticPageUrl,physicalPath
JSONObject jsonObject = JSONObject.parseObject(msg);
Integer fileSysType = jsonObject.getInteger("fileSysType");
String staticPageUrl = jsonObject.getString("staticPageUrl");
String physicalPath = jsonObject.getString("physicalPath");
System.out.println(staticPageUrl);
System.out.println(physicalPath);
switch (fileSysType) {
case 0: //fastdfs
fastDfsDownloadAndCopy(staticPageUrl, physicalPath);
break;
case 1: //hdfs
hdfsDownloadAndCopy(staticPageUrl, physicalPath);
break;
default:
break;
}
}
/**
* 通过fastdfs下载文件,并且拷贝到特定的目录
* @param staticPageUrl
* @param physicalPath
*/
private void hdfsDownloadAndCopy(String staticPageUrl, String physicalPath) {
//@TODO
}
/**
* 通过fastdfs下载文件,并且拷贝到特定的目录
* @param staticPageUrl
* @param physicalPath
*/
private void fastDfsDownloadAndCopy(String staticPageUrl, String physicalPath) {
Response response = fastDfsClient.download(staticPageUrl);
InputStream is = null;
OutputStream os = null;
try {
is = response.body().asInputStream();
os = new FileOutputStream(physicalPath);
IOUtils.copy(is,os);
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}