黑马JavaWeb后端案例开发(包含所有知识点!!!)

news2024/11/15 13:27:58

目录

1.准备工作

环境搭建

开发规范 

 REST(REpresentation State Transfer),表述性状态转换,它是一种软件架构风格

注意事项

统一响应结果

2.部门管理功能

查询部门

 删除部门

新增部门

@RequestMapping 

 3.员工管理功能

分页查询

批量删除员工

​编辑新增员工 

文件上传

简介

本地存储

修改员工

查询回显

修改员工

参数配置化

配置格式

yml数据格式

4.用户登录功能

登录功能

登录校验

会话技术

会话跟踪方案对比

JWT令牌

JWT-生成

JWT-校验

登录-生成令牌

过滤器Filter

入门程序

FIlter执行流程

Filter拦截路径

过滤器链

登录校验Filter

 拦截器Interceptor

快速入门

拦截器-拦截路径

拦截器-执行流程

登录校验Interceptor

 异常处理

5.事务管理

Spring事务管理

事务属性-回滚

事务属性-传播行为

场景

6.AOP(面向切面编程)

AOP概述

AOP核心概念

通知类型 

@PointCut

通知顺序

切入点表达式

execution表达式

 @Annotation注解表达式

连接点

7.配置优先级

8.Bean管理

获取bean

bean作用域

第三方bean

9.SpringBoot原理

自动配置原理

@Conditional注解


1.准备工作

  • 环境搭建

  • 开发规范 

 REST(REpresentation State Transfer),表述性状态转换,它是一种软件架构风格

注意事项
  • REST是风格,是约定方式,约定不是规定,可以打破
  • 描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如:users、emps、books
统一响应结果
  • 前后端交互统一响应结果Result
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code;//响应码,1 代表成功; 0 代表失败
    private String msg;  //响应信息 描述字符串
    private Object data; //返回的数据

    //增删改 成功响应
    public static Result success(){
        return new Result(1,"success",null);
    }
    //查询 成功响应
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    //失败响应
    public static Result error(String msg){
        return new Result(0,msg,null);
    }
}

2.部门管理功能

查询部门

 

/**
 * 部门管理Controller
 */
@Slf4j
@RestController
public class DeptController {

//    private static Logger log = LoggerFactory.getLogger(DeptController.class);

    @Autowired
    private DeptService deptService;

//    @RequestMapping(value = "/depts",method = RequestMethod.GET) //指定请求方式为GET
    @GetMapping("/depts")
    public Result list(){
        log.info("查询全部部门数据");

        //调用service查询部门数据
        List deptList = deptService.list();

        return Result.success(deptList);
    }
}



@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List list() {
        return deptMapper.list();
    }
}



@Mapper
public interface DeptMapper {
    /**
     * 查询全部部门
     * @return
     */
    @Select("select * from dept")
    List list();
}

 删除部门

 /**
     * 删除部门数据
     */
    @DeleteMapping("/depts/{id}")
    public Result delete(@PathVariable Integer id){
        log.info("根据id删除部门:{}",id);

        DeptService.delete(id);
        return Result.success();
    }

  @Override
    public void delete(Integer id) {
         deptMapper.deleteById(id);
    }

 /**
     * 根据id删除部门
     * @param id
     */
    @Delete("delete  from dept where id = #{id}")
    void deleteById(Integer id);

新增部门

 /**
     * 新增部门数据
     */
    @PostMapping("/depts")
    public Result add(@RequestBody Dept dept){
        log.info("新增部门:{}" , dept);
        deptService.add(dept);
        return Result.success();
    }

@Override
    public void add(Dept dept) {
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());

        deptMapper.insert(dept);
    }


 @Insert("insert into mybatis.dept(name, create_time, update_time ) values (#{name},#{createTime},#{updateTime})")
    void insert(Dept dept);

@RequestMapping 


 3.员工管理功能

分页查询

@Slf4j
@RestController
public class EmpController {

    @Autowired
    private EmpService empService;

    @GetMapping("/emps")
    public Result page(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer pageSize){
        log.info("分页查询,参数:{},{}",page,pageSize);
        //调用service分页查询
        PageBean pageBean = empService.page(page,pageSize);
        return Result.success(pageBean);
    }

}

@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;
    @Override
    public PageBean page(Integer page, Integer pageSize) {
        //1.获取总记录数
        Long count = empMapper.count();

        //2.获取分页查询结果列表
        Integer start = (page - 1) * pageSize;
        List<Emp> empList = empMapper.page(start, pageSize);

        //3.封装PageBean对象
        PageBean pageBean = new PageBean(count, empList);
        return pageBean;

    }
}

@Mapper
public interface EmpMapper {

    /**
     * 查询总记录数
     * @return
     */
    @Select("select count(*) from emp")
    public Long count();

    /**
     * 分页查询,获取列表数据
     * @param start
     * @param pageSize
     * @return
     */
    @Select("select * from emp limit #{start},#{pageSize}")
    public List<Emp> page(Integer start,Integer pageSize);
}

批量删除员工

新增员工 

文件上传

简介
  • 文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程

前端页面三要素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>

    <form action="/upload" method="post" enctype="multipart/form-data">
        姓名: <input type="text" name="username"><br>
        年龄: <input type="text" name="age"><br>
        头像: <input type="file" name="image"><br>
        <input type="submit" value="提交">
    </form>

</body>
</html>

服务端接口 

  @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image){
        log.info("文件上传:{},{},{}" ,username,age,image);
        return Result.success();
    }
本地存储
  • 在服务端,接收到上传来的文件之后,将文件存储在本地服务器磁盘中
 @PostMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image) throws IOException {
        log.info("文件上传:{},{},{}" ,username,age,image);
        //获取原始文件名
        String originalFilename = image.getOriginalFilename();

        //构造唯一的文件名 - uuid(通用唯一识别码)
        int index = originalFilename.lastIndexOf(".");
        String extname = originalFilename.substring(index);
        String newFileName = UUID.randomUUID().toString()+ extname;
        log.info("新的文件名: {}" ,newFileName);


        //将文件存储在服务器的磁盘目录中E:\images
        image.transferTo(new File("E:\\images\\" + newFileName));


        return Result.success();
    }

在Springboot中,文件上传,默认单个文件允许最大大小为1M。如果需要上传大文件,可以进行如下配置:

#配置单个文件上传大小限制
spring.servlet.multipart.max-file-size=10MB
#配置单个请求最大大小的限制(一次请求中是可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB

修改员工

  • 查询回显

  • 修改员工

参数配置化

配置格式

yml数据格式
#定义对象/Map集合
user:
  name:Tom
  age:20
  address:beijing

#定义数组/List/Set
hobby:
  - java
  - C
  - game
  - sport

4.用户登录功能

  • 登录功能

@RestController
@Slf4j
public class loginController {

    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        log.info("员工登录:{}",emp);
        Emp e = empService.login(emp);
        return e != null ?Result.success():Result.error("用户名或密码错误");

    }
}

 @Override
    public Emp login(Emp emp) {
        return empMapper.getByUsernameAndPassword(emp);
    }


 /**
     * 根据用户名和密码查询员工
     * @param emp
     * @return
     */
    @Select("select * from emp where username = #{usernae} and password = #{password}")
    Emp getByUsernameAndPassword(Emp emp);
}

登录校验

会话技术
  • 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。
  • 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
  • 会话跟踪方案:
    • 客户端会话跟踪技术:Cookie
    • 服务端会话跟踪技术:Session
    • 令牌技术(企业主流)
会话跟踪方案对比

JWT令牌
  • 全称:JSON Web Token
  • 定义了一张简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息
  • 组成:
    • 第一部分:Header(头),记录令牌类型、签名算法
    • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息
    • 第三部分:Signature(签名),防止Token被篡改、确保安全性

  • 场景:登录认证
    • ①登录成功后,生成令牌
    • ②后续每个请求,都有携带JWT令牌,系统在每次请求处理之前,先校验令牌,通过后,再处理
JWT-生成

JWT-校验

登录-生成令牌
 @Autowired
    private EmpService empService;


    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        Emp e = empService.login(emp);


        //登录成功,生成令牌,下发令牌
        if(e != null){
            Map<String, Object> claims = new HashMap<>();
            claims.put("id",e.getId());
            claims.put("name",e.getName());
            claims.put("username",e.getUsername());
            //生成Jwt令牌
            String jwt = JwtUtils.generateJwt(claims);
            return  Result.success(jwt);
        }


        return Result.error("错误");
    }
过滤器Filter
  • 概念:是JavaWeb三大组件之一
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能
入门程序

@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override  //初始化方法,只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init 初始化方法执行了");
    }

    @Override //拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求");
        //放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override  //销毁方法,只调用一次
    public void destroy() {
        System.out.println("destroy 销毁方法执行了");
    }
}
FIlter执行流程

Filter拦截路径

过滤器链
  • 介绍:一个Web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链
  • 顺序:注解配置的Filter,优先级是按照过滤器类名的自然排序
登录校验Filter

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        //1.获取请求url
        String url = req.getRequestURI().toString();
        log.info("请求的url:{}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行
        if(url.contains("login")){
            log.info("登录操作,放行...");
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        //3.获取请求头中的令牌(token)
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json ---------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //5.解析token,如果解析失败,返回错误结果
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json ---------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行
        log.info("令牌合法,放行");
        filterChain.doFilter(servletRequest, servletResponse);


    }
}
 拦截器Interceptor
  • 概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架提供的,用来动态拦截控制器方法的执行
快速入门

拦截器-拦截路径

拦截器-执行流程

  • 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口
  • 拦截范围不同:过滤器会拦截所有的资源,而拦截器只会拦截Spring环境的资源 
登录校验Interceptor

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行,返回true:放行,返回false,不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        //1.获取请求url
        String url = req.getRequestURI().toString();
        log.info("请求的url:{}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行
        if(url.contains("login")){
            log.info("登录操作,放行...");
            return true;
        }

        //3.获取请求头中的令牌(token)
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json ---------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json ---------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            return false;
        }

        //6.放行
        log.info("令牌合法,放行");
        return true;
    }

    @Override //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    @Override //视图渲染完毕后运行,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}
 异常处理

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) //捕获所有异常
    public Result ex(Exception ex){
        ex.printStackTrace();
        return Result.error("对不起,操作失败,请联系管理员");
    }
}

5.事务管理

Spring事务管理

  • 注解:@Transactional
  • 位置:业务层的方法上、类上、接口上
  • 作用:将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务
 @Transactional //spring事务管理
    @Override
    public void delete(Integer id) {
        deptMapper.deleteById(id);

        int i = 1/0;

        empMapper.deleteByDeptId(id);

    }

事务属性-回滚

rollbackFor:默认情况下,只有出现运行时异常RuntimeException才回滚异常。rollbackFor属性用于控制出现何种异常类型,回滚事务。

  @Transactional(rollbackFor = Exception.class) //spring事务管理
    @Override
    public void delete(Integer id) {
        deptMapper.deleteById(id);

        int i = 1/0;

        empMapper.deleteByDeptId(id);

    }

事务属性-传播行为

propagation:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制

场景
  • REQUIRED:大部分情况下都是用该传播行为
  • REQUIRED_NEW:当我们不希望事务之间相互影响时,可以使用。比如:下订单前需要记录日志,不论订单保存成功与否,都需要保证日志记录能够记录成功

6.AOP(面向切面编程)

AOP概述

  • AOP:Aspect Oriented Programing,其实就是面向特定方法编程
  • 场景:

  • 实现:
    • 动态代理是面向切面编程最主流的实现。而SpringAOP是Spring框架的高级技术,在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程

AOP核心概念

  • 连接点:JoinPoint,可以被AOP控制的方法
  • 通知:Advice,指哪些重复的逻辑,也就是共性功能
  • 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用
  • 切面:Aspect,描述通知与切入点的对应关系(通知+切入点)

通知类型 

@PointCut

  • 该注解的作用是将公共的切入点表达式抽取出来,需要用到时引用该切点表达式即可

通知顺序

切入点表达式

  • 描述切入点方法的一种表达式
  • 作用:主要用来决定项目中的哪些方法需要加入通知
  • 常见形式:
    • 1.execution:根据方法的签名来匹配
    • 2.@annotation:根据注解匹配
execution表达式

 @Annotation注解表达式

连接点

  • 在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等
    • 对于@Around通知,获取连接点信息只能使用ProceedingJoinPoint
    • 对于其他四种通知,获取连接点只能使用JoinPoint,它是ProceedingJoinPoint的父类型


7.配置优先级


8.Bean管理

获取bean

  • 默认情况下,Spring项目启动时,会把bean都创建好放在IOC容器中,如果想要主动获取这些bean,可以通过如下方式:
@Autowired
    private ApplicationContext applicationContext; //IOC容器对象

    //获取bean对象
    @Test
    public void testGetBean(){
        //根据bean的名称获取
        DeptController bean1 = (DeptController) applicationContext.getBean("deptController");
        System.out.println(bean1);

        //根据bean的类型获取
        DeptController bean2 = applicationContext.getBean(DeptController.class);
        System.out.println(bean2);

        //根据bean的名称 及 类型获取
        DeptController bean3 = applicationContext.getBean("deptController", DeptController.class);
        System.out.println(bean3);
}

bean作用域

第三方bean

@Bean

  • 如果要管理的bean对象来自第三方(不是自定义的),是无法用@Component及衍生注解声明bean的,就需要用到@Bean注解
  • 若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过@Configuration注解声明一个配置类
@Configuration //配置类
public class CommonConfig {

    //声明第三方bean
    @Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
          //通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名
    public SAXReader reader(DeptService deptService){
        System.out.println(deptService);
        return new SAXReader();
    }

}


9.SpringBoot原理

  • 起步依赖:依赖传递
  • 自动配置

Springboot的自动配置就是当spring容器启动后,一些配置类、bean对象IU自动存入到了IOC容器,不需要我们手动去声明,简化了开发

自动配置原理

@Conditional注解

  • 作用:按照一定的条件进行判断,在满足条件后才会注册对应的bean对象到Spring IOC容器中
  • 位置:方法、类
  • @Conditional本身是一个父注解,派生出大量的子注解
    • @ConditionalOnClass:判断环境中是否有对应字节码文件,才注册bean到IOC容器

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue前端工程

创建一个工程化的vue项目 npm init vuelatest 全默认回车就好了 登录注册校验 //定义数据模型 const registerDataref({username:,password:,rePassword: }) //校验密码的函数 const checkRePassword(rule,value,callback)>{if (value){callback(new Error(请再次输入密…

受够了限速,用teamOS搭建家庭私有云盘,不再受限于人

在现在这个数字化的年代&#xff0c;手机、电脑、平板&#xff0c;到处都有我的照片、视频和文件。 每次想找个东西都得翻遍所有设备&#xff0c;简直就像大海捞针。 我也试过用那些公有云存储服务&#xff0c;但真的用不惯。首先&#xff0c;我总是担心数据安全问题&#xff…

oracle linux源码安装rabbitMQ并部署三节点rabbitmq集群

一.安装rabbitMQ的基础软件下载 Rabbitmq是现阶段比较常用的一个消息队列服务&#xff0c;是基于erlang语言开放的&#xff0c;需要首先安装erlang&#xff0c;并且rabbitmq和erlang的版本是有关系的。 1.基础依赖软件&#xff08;主要是是编译和erlang安装的时候的一些依赖软…

君正T41开发板环境搭建_串口登陆_配置IP_telnet登陆_mount挂载_安装交叉编译工具链

目录 1 开发板外观 2 串口连接 3芯片内存情况 4 配置IP地址 5 telnet登陆 6 mount挂载目录 7 安装交叉编译工具链 1 开发板外观 2 串口连接 我直接用MobaXterm连接&#xff0c;虽然我还没有文档&#xff0c;但是我觉得波特率大概率就是115200&#xff0c;试了下确实可以…

电流在PCB中的奥秘:《PCB电流与信号完整性设计》解读

我们生活中的每一个电子设备&#xff0c;从简单的家用电器到复杂的通信系统&#xff0c;都依赖于高效、可靠的印制电路板。然而&#xff0c;随着工作频率的提高和电路尺寸的缩小&#xff0c;PCB设计中的信号完整性问题变得日益突出。如何在设计阶段就确保信号的高质量传输&…

Android 10.0 Launcher 启动流程

在前面SystemUI启动流程中说到&#xff0c;在SystemServer中会去启动各种系统服务&#xff0c;这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前&#xff0c;系统四大组件的启动都是在ActivityManagerService中&#xff0c;在android10中…

NPDP学习之路:科学规划顺利拿证

备考策略&#xff1a;制定合理学习计划 开始学习前需要制定一个合理的学习计划是备考过程中的关键。 最好根据自己个人的工作和生活习惯&#xff0c;合理安排每天的学习时间&#xff0c;并合理分配各个知识点的学习进度&#xff0c;把不理解的问题提前记录下来&#xff0c;要…

[渗透测试学习] Editorial-HackTheBox

文章目录 Editorial-HackTheBox信息搜集漏洞利用权限提升参考文章Editorial-HackTheBox 信息搜集 nmap扫描端口 nmap -sV -sC -v 10.10.11.20扫描结果如下 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.…

报销管理软件怎么选?主流的10款对比

国内外排名前十的报销软件大对比&#xff1a;合思、Zoho Expense、金蝶财务报销系统、每刻报销、慧算账、Expensify、齐业成、汇联易、分贝通、QuickBooks Online。 在小型企业中&#xff0c;报销管理可能还可以由财务人员手工完成。然而&#xff0c;对于中到大型企业和快速发展…

『 Linux 』基于阻塞队列的生产者消费者模型

文章目录 生产者-消费者模型概述生产者消费者模型的高效性虚假唤醒信号丢失生产者消费者模型的模拟实现参考代码 生产者-消费者模型概述 生产者消费者模型是一种多线程设计模式,常见于解决多个生产者线程和多个消费者线程之间如何安全有效地共享数据; 该模型中存在三种关系,两个…

多级指针的使用

文章目录 &#x1f34a;自我介绍&#x1f34a;指针的设计规则&#x1f34a;多级指针的结论&#x1f34a;二级指针输出数组中的某个值的表示方法 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &…

Effective Java 中文版(第2版 电子版教程)

前言 Java从诞生到日趋完善&#xff0c;经过了不断的发展壮大&#xff0c;目前全世界拥有了成千上万的Java开发人员。如何编写出更清晰、更正确、更健壮且更易于重用的代码&#xff0c;是大家所追求的目标之一。本书的作者JoshuaBloch曾经是Sun公司的杰出工程师&#xff0c;带…

vite+typescript项目 报错:找不到模块“./*.vue”或其相应的类型声明——解决方案

declare module *.vue {import type { DefineComponent } from vueconst vueComponent: DefineComponent<{}, {}, any>export default vueComponent }

fastjson-1.2.24利用

参考视频&#xff1a;fastjson反序列化漏洞2-1.2.24利用 参考博客&#xff1a;Fastjson系列二——1.2.22-1.2.24反序列化漏洞 分析版本 fastjson1.2.24 JDK 8u141 fastjson反序列化特点 不需要实现Serializable 因为对于找不到符合条件的反序列化器&#xff0c;就把类当作…

SAP ERP 通过SAP PO LDAP适配器与微软AD域服务系统集成案例

一、客户介绍 上海某芯片制造公司的主要产品应用于图像传感器、 图像信号处理芯片、 低功耗芯片、 射频芯片等。专注集成电路技术开发与制造&#xff0c;服务于图像传感器、图形图像信号处理芯片、低功耗芯片、射频芯片等领域的全球客户。 二、项目需求 该企业内部办公电…

Flutter 初识:数据表格和卡片

Flutter数据表格和卡片小结 Table属性解析示例TableRow属性解析 TableCell属性解析 DataTable属性解析示例DataColumn属性解析示例 DataRow属性解析示例 DataCell属性解析 Card属性解析示例 Table Table 是 Flutter 中用于显示表格布局的小部件。它允许你定义行和列&#xff0…

前端日历插件VCalendar

官网地址 API | VCalendar 1.安装 yarn add v-calendarnext popperjs/core 2.全局引入 mian.js //日历插件 import VCalendar from v-calendar; import v-calendar/style.css;app.use(VCalendar); 3.使用 <div><VCalendar reservationTime expanded borderless…

无涯问知AI PC版发布,星环科技开启个人大模型应用新篇章

5月30-31日&#xff0c;2024向星力未来数据技术峰会期间&#xff0c;星环科技推出无涯问知AI PC版&#xff0c;这是一款专为个人用户设计的大模型应用产品&#xff0c;标志着个人智能应用时代的全面展开。 无涯问知AI PC版基于星环科技先进的大模型技术&#xff0c;可以在配备英…

jenkins获取sonarqube质量门禁结果

前景 在使用 Jenkins 集成 SonarQube 时&#xff0c;获取质量门禁&#xff08;Quality Gate&#xff09;结果非常重要。SonarQube 的质量门禁是一种质量控制机制&#xff0c;用于评估代码质量是否符合预设的标准。以下是获取质量门禁结果的意义和作用&#xff1a; 评估代码质量…

跟张良均老师学大数据人工智能-批量集训营开班中

随着我国大数据和人工智能产业的飞速发展&#xff0c;未来社会对高素质科技人才的需求日益旺盛。为助力广大青少年提前掌握前沿技术&#xff0c;实现自我价值&#xff0c;泰迪智能科技多名优秀老师联合打造暑期大数据人工智能集训营&#xff0c;旨在培养具备创新精神和实战能力…