canal+rabbitMQ+thymeleaf+springboot+springcloud(电商商品详情页生成)

1.商品详情页面生成
1.1 实现思路
1). 为什么商品详情页需要静态化处理
由于电商中商品详情页, 在商品一旦审核通过并上架之后, 商品就不会再变化; 所有用户访问到该商品都是相同信息 , 不需要再请求微服务查询数据库 , 效率低 ;

实现静态化, 生成静态页面 , 访问时通过nginx 访问静态页面 , 效率高 ;
2). 实现流程

在这里插入图片描述
1.2 页面微服务搭建
1). pom.xml


com.changgou
changgou_common
1.0-SNAPSHOT


org.springframework.boot
spring-boot-starter-thymeleaf


org.springframework.boot
spring-boot-starter-amqp


com.changgou
changgou_service_goods_api
1.0-SNAPSHOT

2). application.yml
server:
port: 9011
spring:
application:
name: page
rabbitmq:
host: 192.168.200.128
main:
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: false
client:
config:
default: #配置全局的feign的调用超时时间 如果 有指定的服务配置 默认的配置不会生效
connectTimeout: 600000 # 指定的是 消费者 连接服务提供者的连接超时时间 是否能连接 单位是毫秒
readTimeout: 600000 # 指定的是调用服务提供者的 服务 的超时时间() 单位是毫秒
#hystrix 配置
hystrix:
command:
default:
execution:
timeout:
#如果enabled设置为false,则请求超时交给ribbon控制
enabled: true
isolation:
strategy: SEMAPHORE

生成静态页的位置

pagepath: D:\items

3). 引导类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {“com.changgou.goods.feign”})
public class PageApplication {

public static void main(String[] args) {
SpringApplication.run(PageApplication.class,args);
}
}

1.3 Feign接口
在这里插入图片描述
商品详情页面中, 展示的商品信息 包含 : 分类的信息 , spu 信息 , sku信息 ;
@FeignClient(name = “goods”)
public interface CategoryFeign {
@GetMapping("/category/{id}")
public Result findById(@PathVariable(“id”) Integer id);
}
@FeignClient(name = “goods”)
public interface SkuFeign {
@GetMapping("/sku/spu/{spuId}")
public List findSkuListBySpuId(@PathVariable(“spuId”) String spuId);
}
@FeignClient(name = “goods”)
public interface SpuFeign {
@GetMapping("/spu/findSpuById/{id}")
public Result findSpuById(@PathVariable(“id”) String id);
}

1.4 业务层逻辑实现
1). 静态页面的名称
D:/items/{spuId}.html -------------> D:/items/10000001.html , D:/items/10000002.html , D:/items/10000003.html
2). Thymeleaf生成静态页面整体代码结构
Context context = new Context();
context.setVariables(dataModel); //组装数据模型, 封装到Context对象中 ;

templateEngine.process(“templatename” , context , new FileWriter(new File(“D:/items/10000001.html”))); //生成静态页面 ;
3). 获取数据模型
需求:
A. 商品三级分类信息 ;
B. 商品SPU信息 ;
C. 商品SKU列表信息 ;
@Service
public class PageServiceImpl implements PageService {

/**
 * 注入templateEngine用于生成html页面
 */
@Autowired
private TemplateEngine templateEngine;

@Value("${pagepath}")
private String pagepath;

/**
 * 生成商品详情页面
 *
 * @param spuId 商品id
 */
@Override
public void generateItemPage(String spuId) {

    // 2.构建数据模型,封装到context中
    Context context = new Context();
    // 2.1 设置数据
    context.setVariables(getItemData(spuId));
    // 3.使用输出流进行写出页面
    FileWriter fileWriter = null;
    try {
        // 3.1指定文件创建的位置
        File dir = new File(pagepath);
        // 3.2 对文件的位置进行判断, 如果目录不存在就进行创建
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // 3.3 定义文件的名称
        File file = new File(dir + "/" + spuId + ".html");
        fileWriter = new FileWriter(file);

        // 1.调用templateEngine进行生成html页面。
        templateEngine.process("item", context, fileWriter);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (fileWriter != null) {
                fileWriter.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

@Autowired
private SpuFeign spuFeign;

@Autowired
private SkuFeign skuFeign;

@Autowired
private CategoryFeign categoryFeign;

/**
 * 用来封装数据模型
 *
 * @return 封装好的数据模型
 */
private Map<String, Object> getItemData(String spuId) {
    // 0. 创建map用来封装数据
    Map<String, Object> dataMap = new HashMap<>();
    // 1.通过spuFeign远程调用生成spu
    Spu spu = spuFeign.findSpuById(spuId).getData();
    dataMap.put("spu", spu);

    // 2.调用skuFeign生成sku列表
    List<Sku> skuList = skuFeign.findSkuListBySpuId(spuId);
    dataMap.put("skuList", skuList);

    // 3.通过分类feign获取分类的信息
    Category category1 = categoryFeign.findById(spu.getCategory1Id()).getData();
    dataMap.put("category1", category1);
    Category category2 = categoryFeign.findById(spu.getCategory2Id()).getData();
    dataMap.put("category2", category2);
    Category category3 = categoryFeign.findById(spu.getCategory3Id()).getData();
    dataMap.put("category3", category3);

    // 4.通过spu获取图片数据
    if (spu != null) {
        if (StringUtils.isNotEmpty(spu.getImages())) {
            String[] imageList = spu.getImages().split(",");
            dataMap.put("imageList", imageList);

            // 5.获取封装规格的数据,并转换为Map
            Map specificationList = JSON.parseObject(spu.getSpecItems(), Map.class);
            dataMap.put("specificationList", specificationList);
        }
    }

    return dataMap;
}

}

1.5 监听消息队列
1). MQ 中队列及绑定关系声明
@Bean(PAGE_CREATE_QUEUE)
public Queue PAGE_CREATE_QUEUE(){
return new Queue(PAGE_CREATE_QUEUE);
}

@Bean
public Binding PAGE_CREATE_QUEUE_BINDING(@Qualifier(PAGE_CREATE_QUEUE)Queue queue,@Qualifier(GOODS_UP_EXCHANGE)Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with("").noargs();
}

在这里插入图片描述
2). 监听类
@Component
public class PageListener {
@Autowired
private PageService pageService;

@RabbitListener(queues = RabbitMQConfig.PAGE_CREATE_QUEUE)
public void receiveMessage(String spuId){
System.out.println("获取静态化页面的商品id,id的值为: "+spuId);
//条用业务层完成静态化页面生成
pageService.generateHtml(spuId);
}
}

1.6 基于Nginx访问静态页面
1). 上传
需要将本地测试生成的静态页面 ---------------------------------> nginx/html
2). 访问测试
http://192.168.192.152/10000000616300.html

发布了92 篇原创文章 · 获赞 3 · 访问量 2791

猜你喜欢

转载自blog.csdn.net/weixin_44993313/article/details/104501683