阶段七-Day01-SpringMVC

一、Sping MVC的介绍

1. 使用Front(前端)设计模式改写代码

1.1 目前我们的写法

目前我们所写的项目,持久层、业务层的类都放入到Spring容器之中了。他们之间需要注入非常方便,只需要通过@Autowired注解即可。

但是由于Servlet整个生命周期都是被Tomcat进行管理的,一个功能对应一个Servlet并且无法把Servlet放入到Spring容器中。所以每次编写Servlet时都需要编写init方法先获取到Spring容器,然后从Spring容器中取出需要使用的Bean。

1.2 使用Front设计模式的写法

Front(前端)设计模式就是有一个前端(不是前端专业那个前端,是最前面的意思)统一入口,在统一入口根据请求url调用自己的编写的普通方法。

通过一个Servlet进行分发,把每个功能分发到每个单独的普通类的普通方法

1.3 使用Front设计模式优点

这样带来的好处是:

  • 只需要在一个Servlet中编写获取容器Bean的代码,减少了代码冗余。

  • 不需要为每个控制器都创建一个类,而是可以在一个普通Java类中提供普通实例方法代表以前servlet中的service方法。

  • 因为可以自己编写普通Java类,这类可以放入到Spring容器中,注入Service更方便。

  • 同时因为是自己编写的Java,所以可以进行一些封装,对其他操作进行简化。(代码中没有体现)

2. Spring MVC介绍

Spring MVC 虽然在平时认为是一个独立的框架。但其本质为Spring 框架的一个扩展,在Spring官方ZIP包就是一个spring-webmvc.jar的jar包。

Spring MVC在Spring官方的Projects的顶级项目中并没有,可以认为Spring MVC属于Spring Framework的二级子项目。

Spring MVC是基于Front设计模式,总体效果和上面我们自己写的Front结果类似,但Spring MVC作为一个框架,肯定要比我们写的代码复杂很多,功能也强大很多。

Spring MVC中已经帮助编写了前端入口DispatcherServlet,里面编写了请求分发功能,但是并没有提供@WebServlet注解,需要我们在web.xml手动编写<servlet>配置

EmpController在Spring MVC称为控制器类(Handler),里面的方法称为控制单元(HandlerMethod)

M:模型层:包含数据校验

V:视图层: 国际化,标签库

C:控制层: 转发重定向,参数,拦截器,作用域等

3. Spring中的父子容器问题

因为Spring MVC属于Spring的子框架,所以Spring MVC中可以使用Spring框架的全部内容。

Spring 官方为Spring MVC专门定义了一个容器,这个容器里面放Spring MVC中全部Bean,且这个容器属于Spring容器的子容器。

有这样的一个规定:Spring MVC子容器可以调用Spring 父容器的全部内容。但是Spring父容器不能调用Spring MVC子容器内容。

二、Spring MVC环境搭建

1. 创建项目并添加依赖

Spring MVC 在平时随意可以当成一个独立框架看待,但其本质只是Spring Framework中的spring-webmvc.jar文件,这个jar文件依赖了spring web模块和Spring框架核心功能的5个依赖。所以在只使用Spring MVC框架时需要导入spring-webmvc依赖即可。

 <dependencies>
    <!-- 依赖了Spring框架核心功能的5个依赖以及Spring整合Web的依赖spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.16</version>
    </dependency>
  </dependencies>

2. 创建Spring MVC配置文件

与Spring配置文件同理,这个文件的名称是随意的,只要和web.xml中配置对应上就可以。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- springmvc容器配置文件 -->
    <!-- 目的: 扫描@Component注解,将控制器交给springmvc容器-->
    <context:component-scan base-package="com.sh.controller"/>

    <!-- 让Spring MVC的注解生效 -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- 注释驱动 -->
</beans>

3. 编写web.xml内容

因为SpringMVC源码中并没有@WebServlet的注解,所以需要手动配置,在web.xml中配置

web.xml的配置是为了让前端控制器DispatcherServlet生效。并且加载Spring MVC的配置文件。

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

<!-- 配置前端控制器 (DispatcherServlet)-->
  <servlet>
    <servlet-name>ds</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- 为了创建springmvc容器 需要配置springmvc的配置文件 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>

    <!-- tomcat启动之后创建servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>ds</servlet-name>
    <url-pattern>/query</url-pattern>
  </servlet-mapping>

</web-app>
1. 由于配置了 <load-on-startup>1</load-on-startup>
  Tomcat启动时就会创建DispatcherServlet对象
2. DispatcherServlet对象创建后执行初始化方法
   servletConfig对象读取servlet的初始化参数(init-param)
   创建SpringMVC容器.(设置spring容器为父容器,父容器就是一个
   属性,是逻辑上的父子关系,不是继承关系)
   springMVC配置文件中配置了扫描包的注解的路径
   <context:component-scan base-package="com.sh.controller"/>
   通过注解,可以将控制器类交给SpringMVC容器管理
3. 只要获取到了SpringMVC容器就可以获取SpringMVC容器中的控制器类对象
4.DispatcherServlet映射路径为/ ,表示除了.jsp文件,其他全部匹配
5.客户端发起请求,协议://ip:port/query访问资源query与DispatcherServlet
中配置的映射路径(/)可以匹配,通过控制器类找到控制单元,可以根据请求资源和控制
单元的注解值找到对应的控制单元,执行控制单元,处理请求

4. 创建控制器类

Spring MVC自定义控制器类都是以Controller结尾。

这些类都是放在controller的包中。

控制单元方法的访问权限修饰符没有强制要求,但是多写成public的。

控制单元的方法名没有要求,只要满足Java方法名定义要求就可以。

@Controller
public class EmpController {

    /* 控制单元 */
    //请求映射 (控制单元映射的路径,根据该路径可以找到该控制单元)
    @RequestMapping("/query")
    public String query(){
        System.out.println("query");

        /*
        *   最底层默认请求转发,即使不指定返回值,默认也会使用转发
        * */
        return "index.jsp";
    }
}

三、@RequestMapping注解

@RequestMapping注解可以写在控制器类上,也可以写在控制单元方法上。

如果写在类上,表示当前类所有控制单元的映射路径,都以指定路径开头。

如果写在方法上,表示当前方法的映射路径。最终访问这个控制单元的映射路径为:类上@RequestMapping映射路径+方法上@RequestMapping映射路径。

这种在类上写@RequetMapping的写法,在以后做管理类型项目、或网站后台项目中使用的比较多。平时在练习的时候绝大多数是直接在控制单元上写@RequestMapping注解,而不在类上写@RequestMapping。

package com.sh.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


/*
*   @RequestMapping : 可以使用在控制类上,也可以用在控制单元上
*       1. 用在控制类上, 访问控制单元方法时,必须加上控制器类上@RequestMapping中的注解值
*       2. 用在控制单元方法上, 当前控制单元映射的请求路径
*   @RequestMapping注解也映射路径时,可以省略/,例如/emp与emp
*
*   @RequestMapping注解中的属性:
*       1.path : 映射的路径
*                映射一个访问路径: path = {"aa"} 可以省略{}
*                映射多个访问路径: path = {"aa","bb"}
*       2.value:和path作用相同,只有一个value属性时,value可以省略
*       3.name:添加描述信息
*       4.method:只允许使用该种请求方式才能访问
 *               RequestMethod.POST
 *               RequestMethod.GET
 *               ...
 *
 *             简化:
 *               @GetMapping -》 @RequestMapping(method = RequestMethod.GET)
 *               @PostMapping -》@RequestMapping(method = RequestMethod.POST)
 *
 *      5.params:  指定子请求中必须携带的请求参数
 *      6.headers: 指定请求中必须携带的请求头
 *
 * * */
@Controller
@RequestMapping("emp")
public class EmpController {

    /* 控制单元 */
    //请求映射 (控制单元映射的路径,根据该路径可以找到该控制单元)
    @RequestMapping("query")
    public String query(){
        System.out.println("query");

        /*
        *   最底层默认请求转发,即使不指定返回值,默认也会使用转发
        * */
        return "/index.jsp";
    }

    @RequestMapping(path = "aa")
    public String aa(){
        System.out.println("aa");
        return "/index.jsp";
    }

    @RequestMapping(path = {"bb","cc"})
    public String bb(){
        System.out.println("bc");
        return "/index.jsp";
    }


    @RequestMapping(path = "dd",name = "bc")
    public String dd(){
        System.out.println("bc");
        return "/index.jsp";
    }

    //只允许get请求访问
    @RequestMapping(path = "ee" ,method = RequestMethod.GET)
    public String ee(){
        System.out.println("bc");
        return "/index.jsp";
    }

    @RequestMapping(path = "ff",params = "name")
    public String ff(){
        System.out.println("bc");
        return "/index.jsp";
    }

    @RequestMapping(value = "hhh", produces = "text/plain;charset=utf-8")
    @ResponseBody
    //@ResponseBody注解与produces属性一般会一起使用,设置响应的编码与类型
    public String hh(){
        System.out.println("hh() 执行了");
        return "aaa你好";
    }
}

produces只有在使用@ResonseBody注解中才生效。

四、映射路径

1. 映射路径介绍

映射路径在之前Java EE阶段中学习过,就是web.xml中<url-pattern>的值或者@WebServlet("")注解的值。

映射路径无论是在Servlet中还是在Spring MVC中,都表示:当URL中出现指定路径时会执行Servlet的方法或执行Spring MVC的控制单元。

2. 多级路径

映射路径:既然名字中已经叫做路径了,所以写法上也支持路径的写法。

@RequestMapping("/test/test2")
public String test2(){
    return "first.jsp";
}

3. 多级路径中注意事项

3.1 多层路径中最优写法

只需要在返回值中使用绝对路径就可以减少出错的情况。

跳转时 / 表示项目根目录,也就是webapp目录的根目录。

4. Ant风格的映射路径

在Spring MVC中支持Ant风格的映射路径写法。所谓的Ant风格就是支持三种特殊的符号。

符号解释
?匹配任意单字符
*匹配0或者任意数量的字符
**匹配0或者更多数量的目录

解释说明:

使用Ant的特殊符号时,表示模糊匹配。可能出现客户端发送过来的URL能匹配上多个映射路径,这时的优先级为:

固定值 (bjsxt1) > ?形式(bjsxt?) > 一个*号(/*) > (/**)形式

// 优先级最高
@RequestMapping("/sh1")
public String testAnt1(){
    System.out.println("sh");
    return "/first.jsp";
}
// 优先级低于sh1。sh开头,后面跟个任意内容符号
@RequestMapping("/sh?")
public String testAnt2(){
    System.out.println("sh");
    return "/first.jsp";
}
// 优先级低于?。一层路径,任意内容
@RequestMapping("/*")
public String testAnt3(){
    System.out.println("11111");
    return "/first.jsp";
}
// 优先级低于*。任意层路径
@RequestMapping("/**")
public String testAnt4(){
    System.out.println("22222");
    return "/first.jsp";
}

五、Spring MVC 中的转发和重定向

1. 转发和重定向复习

在前面Java EE阶段中学习过两个概念:转发和重定向。这两个概念都是出现在资源之间相互跳转的。

两者区别:

(1)转发为一次请求,tomcat内部跳转。重定向为多次请求,不是tomcat内部跳转。

(2)转发是一次请求,无论服务器内部转发多少次,请求对象都不变。所以转发可以共享请求域的值。同时对于客户端浏览器URL是不变的。

重定向后需要客户端重新发起请求,和重定向之前不是一个请求。所以重定向后不能获取到之前设置在请求域的值。同时客户端浏览器URL是改变的。

(3)转发只能跳转到当前项目内部资源。重定向可以跳转到外部资源。例如:从自己的项目中跳转到百度应该使用重定向。

(4)转发时资源路径如果是绝对路径,第一个 / 表示当前项目根目录。

重定向时资源路径时绝对路径,第一个 / 表示 Tomcat 的 webapps目录,即:当前项目的上层目录。

转发的代码实现:

request.getRequestDispatcher("/first.jsp").forward(request,response);

重定向的代码实现:

response.sendRedirect("/sh/first.jsp");

2. Spring MVC中的转发和重定向

在Spring MVC框架中,默认情况下都使用转发进行寻找资源。

package com.sh.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("dept")
public class DeptController {

    @RequestMapping("query")
    public String query(){
        System.out.println("query");
        return "forward:del";
        //相当于return "del";
        //默认底层就是请求转发
    }

    @RequestMapping("del")
    public String del(){
        System.out.println("del");
        return "forward:/index.jsp";
    }


    //请求重定向只能手动设置
    @RequestMapping("aa")
    public String aa(){
        System.out.println("aa");
        return "redirect:/index.jsp";
    }
    
}

3. Spring MVC转发和重定向时绝对路径

在Spring MVC中无论是转发还是重定向,使用绝对路径时/都表示项目根目录。

这种设计对于开发者来说更加友好,不用在区分到底是转发,还是重定向了。

六、WEB-INF目录资源

1. WEB-INF目录资源介绍

在平时学习过程中,我们多会把JSP文件放入到webapp目录中,或在webapp下新建一个目录把页面资源放入到目录中,这种情况JSP都是可以通过浏览器直接访问的。

但是在一些特定的项目中,从安全性等方面考虑不希望客户端通过浏览器直接访问对应的资源。

这时就可以把资源放入到WEB-INF目录中。因为在Java Web项目中规定:WEB-INF中资源是不允许被客户端直接访问,需要先访问控制器,通过控制器的转发来访问这些资源。

在浏览器地址栏访问suiyi.jsp是无法访问到的。

需要提供一个控制单元方法,转发到JSP页面中。

2. 具体示例

3. 结果分析

如果项目中所有的JSP、CSS、JavaScript、图片都放入到WEB-INF中,那所有的资源都必须先执行控制器。这样对于刚学习这种写法的人可能觉得实现起来更加复杂了。但是从项目角度上却是更加安全了,也可以在控制器方法中加入自己想要加入的逻辑。

七、视图解析器

1. 视图解析器和视图

Spring MVC的控制单元 支持 ModelAndView、String 等多种类型的返回值,但无论控单元的返回值是哪种类型,Spring MVC 内部最终都会将它们封装成一个 ModelAndView 对象,它由 model(模型数据)和 view(逻辑视图名)两部分组成,所以 Spring MVC 需要借助 ViewResolver(视图解析器)将 逻辑视图名解析为真正的 View 视图对象,然后才能响应给客户端展示。

Spring MVC 的核心理念是将 视图与 数据模型进行解耦,视图技术随场景选择:Thymeleaf、JSP、FreeMarker、Excel 等等。

Spring MVC 定义了ViewResolverView接口:

  1. ViewResolver 视图解析器

    视图解析器用来解析逻辑视图,将其解析成真正的视图对象。

    SpringMVC 提供了一个视图解析器的接口 ViewResolver,所有具体的视图解析器必须实现该接口。

    AbstractCachingViewResolver:抽象类,这种视图解析器会把它曾经解析过的视图保存起来,然后每次要解析视图的时候先从缓存里面找,如果找到了对应的视图就直接返回,如果没有就创建一个新的视图对象,然后把它放到一个用于缓存的map中,接着再把新建的视图返回。使用这种视图缓存的方式可以把解析视图的性能问题降到最低。

    ​​

    UrlBasedViewResolver:它是对ViewResolver的一种简单实现,而且继承了AbstractCachingViewResolver,主要就是提供的一种拼接URL的方式来解析视图,它可以让我们通过prefix属性指定一个指定的前缀,通过suffix属性指定一个指定的后缀,然后把返回的逻辑视图名称加上指定的前缀和后缀就是指定的视图URL了。如prefix=/WEB-INF/,suffix=.jsp,返回的视图名称viewName=test,则UrlBasedViewResolver解析出来的视图URL就是/WEB-INF/test.jsp。默认的prefix和suffix都是空串。

    ​​

    InternalResourceViewResolver:它是URLBasedViewResolver的子类,所以URLBasedViewResolver支持的特性它都支持。在实际应用中InternalResourceViewResolver也是使用的最广泛的一个视图解析器。InternalResourceViewResolver解释为内部资源视图解析器。InternalResourceViewResolver会把返回的视图名称都解析为InternalResourceView对象,InternalResourceView会把Controller处理器方法返回的模型数据都存放到对应的request属性中,然后通过RequestDispatcher在服务器端把请求forword到目标URL

    ​​

    ThymeleafViewResolver:Thymeleaf视图解析器,映射成一个 Thymeleaf 模板文件。

    ​​

    FreeMarkerViewResolver:UrlBasedViewResolver的子类。FreeMarkerViewResolver会把Controller处理方法返回的逻辑视图解析为FreeMarkerView。

未完待续 

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

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

相关文章

并查集详解(附例题和模板)

一、并查集 &#xff08;1&#xff09;处理问题的类型 1.将两个集合合并 2.询问两个元素是否在一个集合当中 询问 1.fa[x]a; 2.if(fa[x]fa[y]) o(1) 在o(1)的复杂度内进行两个操作 &#xff08;2&#xff09;基本原理 基本原理&#xff1a;每个集合用一棵树来表示&#…

振南技术干货集:深入浅出的Bootloader(5)

注解目录 1、烧录方式的更新迭代 1.1 古老的烧录方式 (怀旧一下&#xff0c;单片机高压烧录器。) 1.2 ISP 与ICP 烧录方式 (还记得当年我们玩过的 AT89S51?) 1.3 更方便的 ISP 烧录方式 1.3.1串口 ISP &#xff08;是 STC 单片机成就了我们&#xff0c;还是我们成就了…

破解tomcat密码并上传webshell

tomcat基础认证爆破 暴力破解 进入vulnhub的tomcat8目录&#xff0c;启动环境 由于tomcat密码默认最大尝试错误次数为5次&#xff0c;需要修改server.xml&#xff0c;修改下面字段 failureCount"10000000000" lockOutTime"0"tomcat默认界面&#xff0c;…

一个破单机,也要用远程缓存?

大家好&#xff0c;豆小匠终于开始Coding了&#xff0c;这期来聊聊实战相关的杂谈。 正文开始&#xff01; 作为编程萌新的时候&#xff0c;总想着把程序做复杂&#xff0c;堆技术栈。 但是程序是为场景服务的&#xff0c;比如&#xff0c;我想提高接口的响应速度&#xff0c…

传输层协议-UDP协议

目录 传输层再谈端口号端口号范围划分认识知名端口号 UDP协议UDP协议格式UDP数据封装UDP数据分用 UDP协议的特点面向数据报 UDP缓冲区UDP使用注意事项基于UDP的应用层协议 传输层 实际上我们应用层的数据并不是直接发给网络的&#xff0c;而是需要先将数据发送给传输层&#xf…

客户下单时如何自动匹配到最近的门店

有些商家有多个门店&#xff0c;当客户下单时&#xff0c;希望能够将客户下的订单分配给最近的门店。下面就具体介绍一下在采云小程中是如何实现的。 首先&#xff0c;为了简便起见&#xff0c;请确定门店高级设置保持着默认设定。因为单独的商品管理模式以及独享的商品信息模…

一篇博客读懂队列——Queue

目录 一、队列的概念和结构 ​二、队列的实现 2.1队列的初始化QueueInit 2.2队列的摧毁QueueDestroy 2.3插入结点QueuePush 2.4删除结点QueuePop 2.5返回队头QueueFront 2.6返回队尾QueueBack 2.7判断队列为空QueueEmpty 2.8统计队列数目QueueSize 一、队列的概念和…

Vue computed 计算属性

1.计算属性的相关知识 概念 &#xff1a;基于现有的数据&#xff0c;计算出来的新属性。依赖数据的变化&#xff0c;自动重新计算。 语法&#xff1a; ① 声明在 computed 配置项 中&#xff0c;一个计算属性对应一个函数 ② 使用起来和普通属性一样使用 {{ 计算属性名 …

Vue3+Element Plus表格多字段组合排序方法

一、问题描述 默认el-table是单个字段排序的&#xff0c;点击表格头排序&#xff0c;老排序字段的排序箭头样式并没有保留&#xff0c;仅仅保留了新点击字段的样式。 二、实现效果 选择多列组合排序时可以高亮多列箭头。 三、解决方法 3.1 如何记录多个字段被选择&#xff…

C++编译器对临时对象的优化

思考&#xff1a;我们在构造运算符重载号重载的时候会构造那些函数呐&#xff1f;&#xff1f;&#xff1f; 例子&#xff1a;小dome //该运算重载函数 由 左操作数调用&#xff0c;右操作数当做实参传递给该函数//触发t1t3->t1.operator (t3)Test operator (const Test &a…

js写轮播图,逐步完善

目录 1、自动轮播 2、点击更换 3、自动播放加左右箭头点击切换 4、完整版轮播图 1、自动轮播 用定时器setInterval()来写&#xff0c;可以实现自动播放 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><met…

【开源】基于JAVA的超市商品管理系统

目录 一、摘要1.1 简介1.2 项目详细录屏 二、研究内容2.1 数据中心模块2.2 超市区域模块2.3 超市货架模块2.4 商品类型模块2.5 商品档案模块 三、系统设计3.1 用例图3.2 时序图3.3 类图3.4 E-R图 四、系统实现4.1 登录4.2 注册4.3 主页4.4 超市区域管理4.5 超市货架管理4.6 商品…

http接口测试—自动化测试框架设计

一、测试需求描述 对服务后台一系列的http接口功能测试。 输入&#xff1a;根据接口描述构造不同的参数输入值&#xff08;Json格式&#xff09; 输出&#xff1a;字符串&#xff08;传入的方式传入的字符串&#xff09; http://localhost:8090/lctest/TestServer 二、程序设计…

CTFhub-RCE-命令注入

构造payload :127.0.0.1|ls 127.0.0.1|cat 80203153621323.php F12

成绩发布快捷方式

当一名老师&#xff0c;每到学期中期末&#xff0c;是不是觉得成绩发布就像个老大难&#xff1f;学生急着要知道自己的成绩&#xff0c;家长也频繁私信询问成绩&#xff0c;而传统的成绩发布方式却往往效率低下&#xff0c;费时费力。今天就来聊聊如何通过查询系统、各类代码、…

Python数据容器(集合)

集合 1.集合的定义2.集合中常用操作4.常用功能总结5.集合的特点6.练习 思考&#xff1f; 我们目前接触到了列表、元组、字符串三个数据容器了。基本满足大多数的使用场景。为何要学新的集合类型呢&#xff1f; 通过特性分析 列表可以修改、支持重复元素且有序元组、字符串不可修…

EtherNET转Profibus网关使用 AB PLC的配置方法

兴达易控EtherNET转Profibus网关&#xff08;XD-EPPB20&#xff09;是一款功能强大的通讯设备&#xff0c;具备Profibus从站功能。它的主要作用是将EtherNET/IP设备无缝接入到PROFIBUS网络中。通过连接到Profibus总线&#xff0c;它可以作为从站使用&#xff0c;并且通过连接到…

【C++】一维字符数组 与 二维字符数组

一维字符数组 一维字符数组 可以通过数组名直接进行整体输入和输出&#xff08;注意&#xff1a;当使用一维字符数组存储字符串时&#xff0c;因为元素尾部会有一个空字符\0,所以需要给空字符\0留一个位置&#xff09; char a[5]; cin>>a; cout<<a;二维字符数组 …

书单 | 11月程序员新书播报

11月最新上架计算机书籍 1、人工智能&#xff08;第3版&#xff09; 美国经典人工智能教材第3版&#xff0c;人工智能的百科全书&#xff0c;新增深度学习及人工智能编程等内容&#xff0c;理论阐释结合动手实践&#xff0c;附赠PPT课件、配套视频及代码文件。 1.人工智能经典…

SpringCloud微服务:Ribbon负载均衡

目录 负载均衡策略&#xff1a; 负载均衡的两种方式&#xff1a; 饥饿加载 1. Ribbon负载均衡规则 规则接口是IRule 默认实现是ZoneAvoidanceRule&#xff0c;根据zone选择服务列表&#xff0c;然后轮询 2&#xff0e;负载均衡自定义方式 代码方式:配置灵活&#xff0c;但修…