瑞吉外卖问题(待更新...

文章目录

  • 一、session注册时
  • 二、用户增加时
  • 三、RequestBody
    • 3.1 Long问题
    • 3.2 RequestBody
    • 3.3 UpdataById
  • 四、公共填充字段
  • 五、文件上传与下载
    • 5.1 拦截器与过滤器


一、session注册时

刚开始使用的是该代码

   httpServletRequest.setAttribute("employee",emp.getId());

导致我点击登录后,还是一直在登录页面,进不去主页面。
原因是:
我使用的那行代码并没有保存到session里,只是保存到当前请求中。当请求别的页面时,就会失效。
正确代码:

httpServletRequest.getSession().setAttribute("employee", emp.getId());

该代码是保存到当前会话域。

移除的代码:

  httpServletRequest.getSession().removeAttribute("employee");

获取代码:

httpServletRequest.getSession().getAttribute("employee")

当时还比较迷惑一个地方,就是 已经已经排除掉以下页面,就是以下页面直接放行。但是当我请求/backend/index.html 时并不会被直接放行,还是需要先登录,经过检查,

 String[] urls=new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };

原因是:
index.html页面 会直接默认请求一个页面,
在这里插入图片描述
在这里插入图片描述
请求该页面就会被过滤器拦截。

二、用户增加时

ControllerAdvice注解给忘记了,通过该注解可以配置一个全局的信息,其中有一个属性是annotations,: 允许你指定一个或多个类(类型数组),只有继承或实现了这些类的控制器才会受到此 advice 影响。

用途:专门用于处理控制器层的全局异常处理、数据绑定和数据预处理。
应用范围:仅限于 Spring MVC 的控制器层。

原始代码: 使用的是ControllerAdvice

package com.cky.exceptions;

import com.cky.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @ClassName MyExceptions
 * @Description TODO
 * @Author lukcy
 * @Date 2024/6/21 15:51
 * @Version 1.0
 */
@Slf4j
@ResponseBody
@ControllerAdvice(annotations = {RestController.class, Controller.class})
public class MyExceptions {
    /**
     * 异常处理方法
     * @param ex
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> EmpExceptions(SQLIntegrityConstraintViolationException ex) {
        if (ex.getMessage().contains("")) {
            String[] split = ex.getMessage().split("");
            String msg = split[2] + "已存在";
            return R.error(msg);
        }return R.error("未知错误");
        }}

修改后
我没有使用该全局异常,而是在保存时先判断是否存在

public interface EmployeeService extends IService<Employee> {
  boolean isUsernameExist(String username);
}

@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 检查数据库中是否存在指定的用户名
     *
     * @param username 要检查的用户名
     * @return 如果存在返回true,否则返回false
     */
    public boolean isUsernameExist(String username) {
        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        int count = employeeMapper.selectCount(queryWrapper);
        return count > 0;
    }
}
   @PostMapping
    public R<String> saveemp(HttpServletRequest httpServletRequest,@RequestBody Employee employee){
        boolean usernameExist = employeeService.isUsernameExist(employee.getUsername());
        if (usernameExist){
            return R.error(String.format("%s 用户名已经存在", employee.getUsername()));
        }
        //设置默认初始密码
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        //其他字段
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
        Long id = (Long) httpServletRequest.getSession().getAttribute("employee");
        employee.setCreateUser(id);
        employee.setUpdateUser(id);
        //直接调用接口的save方法
        employeeService.save(employee);
        return R.success("员工添加成功");
    }

能够实现同样的功能
在这里插入图片描述

更正
到后边,比如新增菜品或者套餐时,发现还是需要判断名字是否唯一,所以还是需要全局异常类更好些。

package com.cky.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * @ClassName GlobalExceptiobHandler
 * @Description TODO
 * @Author lukcy
 * @Date 2024/6/25 9:56
 * @Version 1.0
 */
@Slf4j
@ResponseBody
@ControllerAdvice(annotations = {RestController.class, Controller.class})
public class GlobalExceptiobHandler {

    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.error(ex.getMessage());

        if (ex.getMessage().contains("Duplicate entry")) {
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + " 已存在";
            return R.error(msg);
        }

        return R.error("未知错误");
    }
}

三、RequestBody

在修改用户状态时:

3.1 Long问题

js 在对Long数据传送时,只会保证前16位有效,做法:增加一个自己的消息转换器+对象转换器,把Long数据转换为String。

package com.cky.common;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);


        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))

                .addSerializer(BigInteger.class, ToStringSerializer.instance)
                .addSerializer(Long.class, ToStringSerializer.instance)
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

package com.cky.config;

import com.cky.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

/**
 * @ClassName WebmvcConfig
 * @Description TODO
 * @Author lukcy
 * @Date 2024/5/29 9:40
 * @Version 1.0
 */
//默认能访问类路径下的static和template文件夹 这里我们没有放在这些文件夹下 所以访问不到,需要自己配置静态资源处理器
@Configuration
@Slf4j
public class WebmvcConfig extends WebMvcConfigurationSupport {
    /**
     * 静态资源映射
     * @param registry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
    }

    /**
     * 增加消息转换器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("配置的消息转换器....");
        MappingJackson2HttpMessageConverter mappingJackson2CborHttpMessageConverter=new MappingJackson2HttpMessageConverter();
        mappingJackson2CborHttpMessageConverter.setObjectMapper(new JacksonObjectMapper());
        converters.add(0,mappingJackson2CborHttpMessageConverter);
    }
}

3.2 RequestBody

刚开始在控制器上没有加上@RequestBody注解,导致传入的参数并不能赋给Employee类。
RequestBody和RequestParam区别
@RequestBody会将请求体中的数据,转换成对象

@RequestParam会从http请求查询参数中提取数据

@RequestParam和@RequestBody是Spring Framework中用于处理HTTP请求的注解,它们有以下区别:

1.数据来源:

@RequestParam: 从HTTP请求的查询参数中提取数据,即从URL中的?key=value形式的参数中获取数据。
@RequestBody: 从HTTP请求的请求体(body)中提取数据,通常用于接收JSON、XML等格式的数据。
2.用法:

@RequestParam: 通常用于处理GET请求或POST请求中的表单数据,例如?name=John&age=30这样的查询参数。
@RequestBody: 通常用于处理POST请求中的非表单数据,例如JSON格式的数据,或者XML格式的数据。
3.数据格式:

@RequestParam: 提取的数据一般是简单类型,如字符串、整数等。
@RequestBody: 提取的数据可以是复杂类型,如自定义的Java对象、Map、List等,通常是用于反序列化JSON或XML数据为Java对象。

3.3 UpdataById

由于Mybatis plus默认的更新策略是NOT_NULL:非 NULL;即通过接口更新数据时数据为NULL值时将不更新进数据库。所以Mybatis plus通过updateById(XXX)更新数据,当用户有更新字段为 空字符串 或者 null 的需求时,需要对 FieldStrategy 策略进行调整。

FieldStrategy 有三种策略:

IGNORED:0 忽略
NOT_NULL:1 非 NULL,默认策略
NOT_EMPTY:2 非空

四、公共填充字段

比如employee中 创建人,修改人,创建时间,修改时间都属于公共字段,我们没必要写到controller中,可以通过mybatispuls的公共填充机制。
在这里插入图片描述
①实体类中
在这里插入图片描述

还有一个问题就是我们自己编写的配置类没有办法获取http的请求,所以id如何获得呢?
在这里插入图片描述
解决:使用ThreadLocal
每个
每次http请求都对应一个线程。
在这里插入图片描述
在这里插入图片描述

package com.cky.common;

/**
 * @ClassName MythreadLocal
 * @Description TODO
 * @Author lukcy
 * @Date 2024/6/25 9:21
 * @Version 1.0
 */

/**
 * 线程工具类
 */
public class MythreadLocal {
    //因为存放的是id 所以是lONG
    private static ThreadLocal<Long> threadLocal=new ThreadLocal<>();

    public static void setCurrendId(Long id){
        threadLocal.set(id);
    }

    public static Long getCurrendId(){
        return threadLocal.get();
    }
}

在filter中已经登录后在threadLocal中保存id,在我们编写的元数据处理配置类中获取id。
在这里插入图片描述

package com.cky.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * @ClassName MyMetaObjectHandler
 * @Description TODO
 * @Author lukcy
 * @Date 2024/6/25 9:12
 * @Version 1.0
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
      metaObject.setValue("createTime", LocalDateTime.now());
      metaObject.setValue("updateTime", LocalDateTime.now());
      metaObject.setValue("createUser", MythreadLocal.getCurrendId());
      metaObject.setValue("updateUser",MythreadLocal.getCurrendId() );
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        long id = Thread.currentThread().getId();
        log.info("当前线程id{}",id);
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser",MythreadLocal.getCurrendId());
    }
}

控制器中这些就可以省略了。
在这里插入图片描述

五、文件上传与下载

5.1 拦截器与过滤器

请求处理顺序总结
前端请求拦截器:在请求发出之前处理请求。
后端过滤器:在请求到达控制器之前进行预处理。
后端拦截器:在请求到达控制器之前进行进一步的处理。
控制器:处理请求并生成响应。
后端拦截器(响应阶段):在响应返回之前处理响应。
后端过滤器(响应阶段):在响应返回之前进行进一步的处理。
前端响应拦截器:在响应返回到客户端之前处理响应。

AJAX请求:前端拦截器(如axios拦截器)会处理请求和响应,然后请求会经过后端过滤器和拦截器,最后到达控制器。
非AJAX请求:不会经过前端拦截器,而是直接发送到服务器。请求会先经过后端过滤器和拦截器,最后到达控制器。
因此,对于非AJAX请求,前端的axios拦截器(request.use 和 response.use)将不会被触发。这些请求只会经过后端的过滤器和拦截器进行处理。

写上述是因为把upload.html 加入之后,返回的是200,相应内容在这里插入图片描述
我在想,为什么这里也没有登录并且common/page 并没有在过滤器里配置,怎么没有返回到login页面。

原因:
因为emlment-upload 组件 是一个普通的http请求,该请求会经过我们的后端过滤器,所以返回了NOTLOGIN(我们在过滤器里面配置的),由于他不是一个ajax请求,所以并不会经过我们的前端拦截器的请求和相应。所以不会跳转到登录页面,我们可以看到登录页面是在前端拦截器的响应中写的。
在这里插入图片描述

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

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

相关文章

探索Linux的奇妙世界:第二关---Linux的基本指令(上篇)

1. xshell与服务器的连接 想必大家在看过上一期视频时已经搭建好了Linux的环境了并且已经下好了终端---xshell了吧?让我来带大家看一看下好了是什么样子的: 第一次登陆会让你连接你的服务器,就是我们买的云服务器,买完之后需要把公网地址ip复制过来进行链接,需要用户名和密码连…

操作系统入门 -- 内存管理

操作系统入门 – 内存管理 1.内存种类 1.1 虚拟内存&#xff08;VIRT&#xff09; 进程需要的虚拟内存大小&#xff0c;包括进程使用的库、代码、数据以及malloc、new分配的堆空间和栈空间等。若进程申请了10MB内存但实际使用了1MB&#xff0c;则物理空间会增长10MB。 1.2 …

红酒达人教你秘技:选酒、存酒,一招一式皆学问

在繁忙的都市生活中&#xff0c;红酒不仅仅是一种饮品&#xff0c;更是一种生活态度&#xff0c;一种品味的象征。然而&#xff0c;面对琳琅满目的红酒品牌与种类&#xff0c;如何选择一瓶心仪的红酒&#xff0c;又如何妥善保存&#xff0c;使其保持很好口感&#xff0c;成为了…

Linux上搭建邮件服务

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 Linux上搭建邮件服务 前言电子邮件的工作原理和基本组成部分1. 电子邮件的工作原理2. 电子邮件的…

天热了,喜欢游泳的朋友的好去处,气膜游泳馆—轻空间

随着夏季的到来&#xff0c;气温不断攀升&#xff0c;游泳成为许多人消暑解热的首选运动。然而&#xff0c;传统的室外游泳池受天气影响较大&#xff0c;室内游泳馆又常常人满为患。对于那些既想避开烈日&#xff0c;又想享受优质游泳体验的朋友们来说&#xff0c;气膜游泳馆无…

MySQL学习(3):SQL语句之DDL

1.SQL通用语法与分类 &#xff08;1&#xff09;通用语法 &#xff08;2&#xff09;分类 2.DDL 2.1数据库操作 show DATABASES; #查询所有数据库select DATABASE(); #查询当前数据库create DATABASE 数据库名称 [default charest 字符集] [collate 排列规则]; #default cha…

2021年03月Python三级真题+答案(中国电子学会 )

2021年03月Python三级真题 一、选择题 1.下列代码的输出结果是&#xff1f;&#xff08; D &#xff09; x 0x10 print(x) A.2 B.8 C.10 D.16 2.关于语句fopen(d:/a.txt, r)&#xff0c;下列描述不正确的是&#xff1f;&#xff08; C &#xff09; A.f是变量 B.r以…

《PyTorch计算机视觉实战》:一、二章

目录 第一章&#xff1a;人工神经网络基础 比较人工智能和传统机器学习 人工神经网络&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09; 是一种受人类大脑运作方式启发而构建的监督学习算法。神经网络与人类大脑中神经元连接和激活的方式比较类似&#xff0…

从灵感到成品:使用AI生成博客文章的完整指南

在信息爆炸的时代&#xff0c;每个人都有讲述自己故事的权利和需求。博客作为一种表达方式&#xff0c;不仅能记录个人经历&#xff0c;还能分享知识和观点。然而&#xff0c;许多人在写博客文章时&#xff0c;常常会遇到灵感枯竭、时间不够用或者不知道如何开始等问题。幸运的…

‘pip‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…

什么是CMSIS || 标准库与HAL库

一&#xff0c;ARM&#xff08;Cortex Microcontroller Software Interface Standard&#xff09; ARM Cortex™ 微控制器软件接口标准&#xff08;Cortex Microcontroller Software Interface Standard&#xff09;是 CortexM 处理器系列的与供应商无关的硬件抽象层。…

Qt 学习(一) addressbook

Qt Demo: addressbook (1)创建项目&#xff1a;选择不创建界面&#xff0c;即UI&#xff0c;此时会自动生成的文件如图所示&#xff1a; QApplication&#xff1a; MainWindow 继承自 QMainWindow&#xff0c;根据需要设计的界面样式。 (2)确定MainWindow 的成员变量 首先&…

如何运用Midjourney探究新中式美学?

新中式美学最近真是越来越火了&#xff0c;把传统中式元素和现代设计结合起来&#xff0c;不仅看着舒服&#xff0c;还特别有文化韵味。 1. 研究和准备 首先&#xff0c;得先弄清楚什么是新中式美学。说白了&#xff0c;就是把传统中式元素和现代设计结合起来。你可以看看相关…

RabbitMQ实践——超时消息的处理方法

大纲 准备工作整个队列的消息都有相同的时效性抛弃超时消息新建带x-message-ttl的队列新建绑定关系实验 超时消息路由到死信队列新建带死信和ttl的队列新建绑定关系实验 消息指定自己的超时时间新建带死信的队列绑定实验 消息自带TTL和队列TTL的关系消息TTL < 队列指定TTL消…

使用 Ubuntu x86_64 平台交叉编译适用于 Linux aarch64(arm64) 平台的 QT5(包含OpenGL/WebEngine支持) 库

使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库 目录 使用 Ubuntu AMD64 平台交叉编译适用于 Linux ARM64 平台的 QT5(包含 OpenGL/WebEngine 支持) 库写在前面前期准备编译全流程1. 环境搭建2. 复制源码包并解压&#xff0c;创…

django 和 pyecharts实现可视化大屏(完整代码)

1.配置settings文件 &#xff08;1&#xff09;注意&#xff1a;需要先创建app(djnago-admin startapp app名称) &#xff08;2&#xff09;配置模板文件 DIRS: [os.path.join(BASE_DIR, templates)], &#xff08;3&#xff09;配置静态文件(这里我由于存放清洗好的需要进行可…

数据结构与算法笔记:高级篇 - 位图:如何实现网页爬虫中的URL去重功能?

概述 网页爬虫是搜索引擎中的非常重要的系统&#xff0c;复杂爬取几十亿、上百亿额度网页。爬虫的工作原理是&#xff0c;通过解析已经爬取网页中的网页链接&#xff0c;然后再爬取这些链接对应地网页。而同一个网页链接有可能被包含在多个页面中&#xff0c;这就会导致爬虫在…

测试开发是什么?为什么现在那么多公司都要招聘测试开发?

测试开发是一种软件开发过程中的一种角色&#xff0c;旨在提高软件质量并确保软件功能完善和稳定。测试开发人员负责编写和执行自动化测试脚本&#xff0c;创建测试工具和框架&#xff0c;以及与开发人员紧密合作&#xff0c;提供实时反馈和改进。 为什么现在那么多公司都要招…

RISC-V异常处理流程概述

RISC-V异常处理流程概述 一、RISC-V异常处理流程和异常委托1.1 异常处理流程1.2 异常委托二、RISC-V异常处理中软件相关内容2.1 异常处理准备工作2.2 异常处理函数2.3 Opensbi系统调用的注册三、参考资料一、RISC-V异常处理流程和异常委托 1.1 异常处理流程 发生异常时,首先…

聚乙烯醇(PVA)涂布型薄膜是高阻隔性包装材料 我国市场增长快速

聚乙烯醇&#xff08;PVA&#xff09;涂布型薄膜是高阻隔性包装材料 我国市场增长快速 聚乙烯醇&#xff08;PVA&#xff09;涂布型薄膜&#xff0c;是以其他塑料薄膜&#xff08;主要是双向拉伸薄膜&#xff09;为基材&#xff0c;以聚乙烯醇为涂料&#xff0c;经表面涂布后制…