SpringMVC总结帖

  SpringMVC是基于MVC设计理念的一款优秀的Web框架,是目前最流行的MVC框架之一,SpringMVC通过一套注解,让POPJ成为处理请求的控制器,而无需实现任何接口,然后使用实现接口的控制器也完全没问题;支持REST风格的URL请求;采用松散耦合架构,比其他MVC框架更具有灵活性和扩展性。关于SpringMVC工程如何搭建请点击:Spring学习之第一个Spring MVC程序(IDEA开发环境)。

 

0 XML配置文件

  web.xml配置DispatcherServlet,DispatcherServlet默认会加载/WEB-INF/xxx-servlet.xml的Spring配置信息,启动Web层的Spring容器。当然,也可以通过配置contextConfigLocation来自定义配置文件名称和位置,如下所示:

<servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/springmvc-servlet.xml</param-value></init-param><load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

0.1 xxx-servlet.xml配置

  xxx-servlet.xml中一般配置自动扫描的包信息、HandlerMapping、ViewResolver,如果没有配置HandlerMapping,则默认使用的是BeanNameURLHandlerMapping;如果没有配置ViewResolver,则默认使用的InternalResourceViewResolver。

<!-- 配置自定义扫描的包-->
<context:component-scan base-package="com.luoxn28"></context:component-scan><!-- ViewResolver 视图解析器 如果没有配置的话,则InternalResourceViewResolver就是默认的 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="order" value="1"/> <!-- ViewResolver优先级 --><!-- 前缀 和 后缀 --><property name="prefix" value="/"/><property name="suffix" value=".jsp"/>
</bean>

 

1 使用@RequestMapping映射请求

  SpringMVC中使用@RequestMapping注解为handler指定可以处理那些URL请求,该注解可以在方法及类定义处使用,DispatcherServlet处理请求时,通过handler的@RequestMapping提供的映射信息确定请求的处理类(或方法)。@RequestMapping在类和方法定义不同之处在于:

  • 类定义处:提供初步的请求映射信息,相对于 WEB 应用的根目录。
  • 方法处:提供进一步的细分映射信息。,相对于类定义处的 URL,若类定义处未标注@RequestMapping,则方法处标记的 URL 相对于WEB 应用的根目录。

使用@RequestMapping示例如下所示:

@Controller
@RequestMapping("/test")
public class Test {@RequestMapping("/testperson")public String testUser(Person person) {System.out.println(person);return "index";}
}

1.1 @RequestMapping映射请求头、请求方法、参数

  @RequestMapping 除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数及请求头映射请求,这些从@RequestMapping注解源码也可以看得出来。@RequestMapping 的 value、method、params 及 heads分别表示请求 URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。

@RequestMapping(value = "/delete", method = RequestMethod.POST, params = "userId")
public String delete() {// ...return "xxx";
}@RequestMapping(value = "/show", headers = "contentType=text/*")
public String show() {// ...return "xxx";
}

1.2 @RequestMapping映射URL绑定的占位符

  带占位符的URL是Spring3.0之后新增的功能,该功能是SpringMVC向REST风格挺进发展一个重要标志。通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable("xxx") 绑定到操作方法的入参中。

@RequestMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id) {UserDao.delete(id);return "index";
}

  ps: 关于什么是REST请翻到最后:finally REST部分。

 

2 映射请求参数

  • Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中。
  • Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
  • 必要时可以对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader 等)、SpringMVC 框架会将 HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。

2.1 使用@RequestParam绑定请求参数

  在方法入参出使用@RequestParam把请求参数传递到方法中。-value是参数名,-requered是否必须,默认为true,表示如果该请求参数中不存在对应的参数,则抛出异常。

@RequestMapping("/userinfo")
public String getUserInfo(@RequestParam(value = "usrename", required = false) String username,@RequestParam("age") int age) {// ...return "xxx";
}

2.2 使用@RequestHeader绑定请求头参数

  请求头包含了若干个属性,服务器可据此获知客户端的信息,通过@RequestHeader即可将请求头中的属性值绑定到处理方法的入参中。

@RequestMapping("/hreaderinfo")
public String getUserInfo(@RequestHeader("Accept-Encoding") String encoding) {// ...return "xxx";
}

2.3 使用@CookieValue绑定Cookie值

@RequestMapping("/sessioninfo")
public String getUserInfo(@CookieValue("sessionId") String sessionId) {// ...return "xxx";
}

2.4 使用POPJ对象绑定请求参数值

  Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。

@RequestMapping("/personinfo")
public String getUserInfo(Person person) {// ...return "xxx";
}

  当请求URL为 /personinfo?name=luoxn28&age=23 时,就会进行POPJ对象的填充,Person类如下所示:

public class Person {String name;int age;// xxx
}

2.5 使用ServletAPI类型的参数

@RequestMapping("/servlet")
public String getUserInfo(HttpServletRequest request, HttpServletResponse response) {// ...return "xxx";
}

  SpringMVC的handler方法可以接受HttpServletRequest/HttpServletResponse/HttpSession或者是java.security.Principal/Locale/InputStream/OutputStream/Reader/Writer类型的参数。

 

3 处理数据模型

  SpringMVC有几种方式用于数据模型输出,有ModelAndView、Map及Model、@SessionAttributes、@ModelAttribute等。

  • ModelAndView: 处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。
  • Map及Model: 入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map中的数据会自动添加到模型中。
  • @SessionAttributes: 将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性。
  • @ModelAttribute: 方法入参标注该注解后, 入参的对象就会放到数据模型中。
@RequestMapping("/model")
public String getUserInfo(Map<String, Object> map) {map.put("time", new Date());return "xxx";
}
@Controller
@RequestMapping("/test")
@SessionAttributes("time")
public class Test {@RequestMapping("/session")public String getUserInfo(Map<String, Object> map) {map.put("time", new Date());return "index";}
}

  当访问url为 /test/session 时,会往服务器session中加入time属性,其值为当前时间(new Date())。

@ModelAttribute

  在方法定义上使用 @ModelAttribute 注解:Spring MVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法。
  在方法的入参前使用 @ModelAttribute 注解:

  • 可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象中,再传入入参
  • 将方法入参对象添加到模型中
@Controller
@RequestMapping("/test")
@SessionAttributes("time")
public class Test {/*** 该方法会往隐含模型中添加一个名为time的模型数据* 注意:同一个浏览器同一段时间内,该函数只会被调用一次*/@ModelAttribute("time")public Date getDate() {Date time = new Date();System.out.println("getDate -- " + time);return time;}@RequestMapping("/model")public String getUserInfo(@ModelAttribute("time") Date time, Map<String, Object> map) {System.out.println(time);map.put("date", new Date());return "index";}
}

3.1 由@SessionAttribute引发的异常

  如果在处理类定义处标注了@SessionAttributes(“xxx”),则尝试从会话中获取该属性,并将其赋给该入参,然后再用请求消息填充该入参对象。如果在会话中找不到对应的属性,则抛出 HttpSessionRequiredException 异常。

  所以,为了避免发生异常,一般都会在请求到达handler方法前往数据模型(session域)中添加属性,比如上面代码中的public Date getDate()方法一样。

 

4 视图和视图解析器

  SpringMVC是如何解析视图的呢?在handler方法返回String、ModelAndView或者View后,都会被SpringMVC内部转换为ModelAndView类型(如果handler方法为void类型的,则该方法自己负责数据渲染和返回结果)。

  Spring MVC 借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是 JSP ,也可能是Excel、JFreeChart 等各种表现形式的视图。对于最终究竟采取何种视图对象对模型数据进行渲染,handler并不关心,handler工作重点聚焦在生产模型数据的工作上,从而实现 MVC 的充分解耦。

4.1 视图

  视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。SpringMVC中定义了一个View接口,源码如下,视图对象有视图解析器负责实例化,是无状态的,所以不会有线程安全问题。

public interface View {String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";String PATH_VARIABLES = View.class.getName() + ".pathVariables";String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";String getContentType();void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;}

常用的视图实现类

4.2 视图解析器

  SpringMVC 为逻辑视图名的解析提供了不同的策略,可以在 Spring WEB 上下文中配置一种或多种解析策略,并指定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。视图解析器的作用比较单一:将逻辑视图解析为一个具体的视图对象。所有的视图解析器都必须实现 ViewResolver 接口。常用的视图解析器实现类如下所示:

  可以选择一种视图解析器或混用多种视图解析器,每个视图解析器都实现了 Ordered 接口并开放出一个 order 属性,可以通过 order 属性指定解析器的优先顺序,order 越小优先级越高。SpringMVC 会按视图解析器顺序的优先顺序对逻辑视图名进行解析,直到解析成功并返回视图对象,否则将抛出 ServletException 异常。

  InternalResourceViewResolver是最常用的视图解析器,也是默认的视图解析器,负责解析JSP视图,使用方式如下所示:

<!-- ViewResolver 视图解析器 如果没有配置的话,则InternalResourceViewResolver就是默认的 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="order" value="1"/> <!-- ViewResolver优先级 --><!-- 前缀 和 后缀 --><property name="prefix" value="/"/><property name="suffix" value=".jsp"/>
</bean>

4.3 关于重定向

  一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理。如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和redirect: 当成指示符,其后的字符串作为 URL 来处理。

  • redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作
  • forward:success.jsp:会完成一个到 success.jsp 的转发操作
@RequestMapping("/forward")
public String getUserInfo(Map<String, Object> map) {//...return "redirect:index";
}

 

5 REST编程

  实现rest风格的增删改查,增删改查的对象是Person类,源码如下:

package com.luoxn28.attribute;import org.springframework.stereotype.Repository;import java.util.HashSet;
import java.util.Set;@Repository
public class Person {String name;int age;public static Set<Person> persons = null;static {persons = new HashSet<Person>();persons.add(new Person("aaa", 12));persons.add(new Person("bbb", 16));persons.add(new Person("ccc", 18));persons.add(new Person("ddd", 24));}public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
Person类

  显示Person、删除Person、更新Person页面list.jsp源码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html>
<head><title>Title</title><script type="text/javascript" src="/js/jquery-1.9.1.min.js"></script><script type="text/javascript">$(function(){$(".delete").click(function(){var href = $(this).attr("href");$("form").attr("action", href).submit();return false;});})</script>
</head>
<body><form action="" method="POST"><input type="hidden" name="_method" value="DELETE"/></form><c:forEach var="person" items="${persons}">姓名:${person.name} <br/>年龄:${person.age} <br/><a class="delete" href="/rest/person/${person.name}">删除</a><a href="/rest/person/${person.name}">更新</a><hr/></c:forEach></body>
</html>
list.jsp

  添加Person页面post.jsp源码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html>
<head><title>Title</title>
</head>
<body><form action="/rest/person" method="post">名字<input type="text" name="name" placeholder="名字"/> <br/>年龄<input type="text" name="age" placeholder="年龄"/> <br/><input type="submit" value="提交"/></form></body>
</html>
post.jsp

  Rest处理类源码如下所示:

package com.luoxn28.rest;import com.luoxn28.attribute.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import java.util.Iterator;
import java.util.Map;
import java.util.Set;@Controller
@RequestMapping("/rest")
public class Rest {// 显示所用Person@RequestMapping("/persons")public String persons(Map<String, Set<Person>> map) {map.put("persons", Person.persons);return "list";}// 添加Person@RequestMapping(value = "/person", method = RequestMethod.POST)public String personPost(Person person, Map<String, Set<Person>> map) {Person.persons.add(person);map.put("persons", Person.persons);return "list";}// 删除Person@RequestMapping(value = "/person/{name}", method = RequestMethod.DELETE)public String personDelete(@PathVariable("name") String name, Map<String, Set<Person>> map) {Iterator<Person> iter = Person.persons.iterator();while (iter.hasNext()) {if (iter.next().getName().equals(name)) {iter.remove();System.out.println("删除成功 " + name);}}map.put("persons", Person.persons);return "redirect:/rest/persons";}// 更新Person@RequestMapping(value = "/person/{name}", method = RequestMethod.GET)public String personUpdate(@PathVariable("name") String name, Map<String, Set<Person>> map) {Iterator<Person> iter = Person.persons.iterator();while (iter.hasNext()) {Person person = iter.next();if (person.getName().equals(name)) {person.setAge(0);System.out.println("更新成功 " + name);}}map.put("persons", Person.persons);return "redirect:/rest/persons";}}

 

finally REST

  REST:即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。
表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。

状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

REST示例

  • – /order/1 HTTP GET :得到 id = 1 的 order
  • – /order/1 HTTP DELETE:删除 id = 1的 order
  • – /order/1 HTTP PUT:更新id = 1的 order
  • – /order HTTP POST:新增 order

 

参考资料:

  1、尚硅谷SpringMVC学习视频及资料

  2、Spring学习之第一个Spring MVC程序(IDEA开发环境)

转载于:https://www.cnblogs.com/luoxn28/p/5608371.html

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

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

相关文章

基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

关 于 解 析 php 的 问 题

在搭建discuz论坛的时候出的问题&#xff0c;上次搭建用的是2.2版本&#xff0c;这次下了个2.4版的Apache发现有好多地方不一样&#xff1b;比如在order deny allow 方面就变了Deny from all变成Require all deniedAllow from all变成Require all granted今天在配置完后开始在浏…

【摄影测量原理】第三章:双像立体测图

本章主要内容: 第一节 人眼的立体视觉和立体观测第二节 立体像对相对定向和核线几何第三节 立体像对的前方交会第四节 单元模型的绝对定向第五节 双像解析摄影测量 第一节 人眼的立体视觉和立体观测 1.1 人眼的立体视觉 人用双眼判断景物可判断其远近,得到…

linux源码编译emqttd,emqtt编译及简单测试记录

emqtt&#xff1a;在Erlang中实现的MQTT客户端库和命令行工具&#xff0c;支持MQTT v5.0 / 3.1.1 / 3.1。下载源码编译cd emqtt & make运行./rebar3 shell测试1、初始化{ok, ConnPid} emqtt:start_link([{clientid, "2020"},{keepalive, 0},{proto_ver, v5},{ho…

《看聊天记录都学不会C语言?太菜了吧》(18)2分钟搞结构体

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖…

「System Design」设计一个短链接系统

短链接系统可以把比较长的 URL 网址转换成简短的网址字符串&#xff0c;短链接的优势是方便传播。适合在一些对字符串长度有要求的场景中使用&#xff0c;比如短信&#xff0c;微博等&#xff0c;比如https://www.cnblogs.com/myshowtime/p/16227260.html转换成短链接为https:/…

iOS中 Animation 动画大全 韩俊强的博客

每日更新关注:http://weibo.com/hanjunqiang 新浪微博&#xff01; iOS开发者交流QQ群&#xff1a; 4463102061.iOS中我们能看到的控件都是UIView的子类,比如UIButton UILabel UITextField UIImageView等等 2.UIView能够在屏幕的显示是因为在创建它的时候内部自动添加一个CALa…

IROS 2017上,这些厂商将会给我们展示什么样的黑科技?

相比起大多数AI学术会议&#xff0c;机器人领域最具影响力的学术会议IROS要“好看”得多。在这个学术会议上不仅会有AI和机器人领域最新的研究成果的论文展示&#xff0c;更有不少来自于科研机构和机器人领域公司机器人&#xff0c;向我们展示着展示机器之美。 比如&#xff0c…

《看聊天记录都学不会C#?太菜了吧》(3)变量:我大哥呢?$:小弟我罩着你!

本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新。 若…

linux block设备,Linux I/O Block--块设备的表示

块设备的分区信息由struct hd_struct结构描述&#xff0c;其中最重要的信息就是分区的起始扇区号和分区的大小。所有分区信息都一起保存在gendisk的part_tbl结构中&#xff0c;同时每个分区的block_device也可以通过bd_part来查询对应的分区信息。下图描述了block_device,gendi…

请来围观:WPF开发的微信客户端!!!

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;眾尋原文链接&#xff1a;https://www.cnblogs.com/ZXdeveloper/p/6058206.html公司的同事离职了&#xff0c;接下来的日子可能会忙碌&#xff0c;能完善DEMO的时间也会少了&#xff0c;因…

ios-新浪微博-下拉刷新获取最新的消息(解决消息重复的问题)(五)

2019独角兽企业重金招聘Python工程师标准>>> 第一步 在上一篇博文的基础上&#xff0c;利用新浪提供的since_id进行判断&#xff0c;在刷新监听的方法中&#xff0c;引入下面的代码 结果如下图 转载于:https://my.oschina.net/iOSliuhui/blog/520495

《看聊天记录都学不会Python到游戏实战?太菜了吧》(7)我用函数写了个特洛伊木马

本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新。 若…

linux修改windows注册表,妙招:让修改的注册表立即生效的几种方法

建站学院(LieHuo.Net)Windows文档Windows操作系统是全球最广泛&#xff0c;使用者最多的软件&#xff0c;熟悉Windows软件成了电脑操作者必不可少的功课&#xff0c;注册表作为“Windows的神经系统”非常重要&#xff0c;相信很多朋友都非常熟悉注册&#xff0c;在开始&#xf…

Android之通过用户名和密码连接指定wifi热点(兼容Android9.0和Android10.0和addNetwork(wifiNewConfiguration)返回-1问题)

1 需求 通过用户名和密码连接指定wifi热点,网上的代码乱七八糟,没几个可以用,我这边整理了下,测试了华为Android9.0和小米Android9.0和10.0和OPPO Android9.0 都没问题,直接回调结果就行。 2 问题 在Android10.0手机上 mWifiManager.addNetwork(wifiNewConfiguration);…

WPF怎么做新手引导界面?

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;眾尋原文链接&#xff1a;https://www.cnblogs.com/ZXdeveloper/p/8391864.html这两天不忙&#xff0c;所以&#xff0c;做了一个简易的新手引导小Demo。因为&#xff0c;不是项目上应用&a…

《看聊天记录都学不会C语言?太菜了吧》(19)巩固开始,数字1、2、3、4能够组成多少个 3 位数的不同的排列

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖…

【经典回放】多种语言系列数据结构算法:串(C版)

我们这里说的串、就是标准的C语言的串,这点,和我们教材中另行定义的串并不一致。我们这里强调仅仅是按C语言的标准处理串,是因为你会按C语言的标准构造串、而不是按其它的模式定义的。在我们的教材上,串相当与一个: struct ElemType {char *str; }; 构造的顺序表、或者是…

可以只读的 ServiceCollection

可以只读的 ServiceCollectionIntro在 .NET 7 Preview 4 中&#xff0c;ServiceCollection 可以声明为只读了&#xff0c;这使得我们可以有效避免在构建了 ServiceProvider 之后再新增服务&#xff0c;导致服务注册失败。Sample在新的版本中&#xff0c;ServiceCollection 新增…

阿里云与中国联通首个公共云平台上线

11月8日&#xff0c;阿里云与中国联通关于公共云合作的首个项目&#xff1a;浙江联通“沃云Powered by Alibaba cloud” 平台&#xff08;cloud.10010zj.com.cn&#xff09;正式发布上线。该平台将以沃云品牌为客户提供“阿里云联通”服务&#xff0c;结合阿里云技术及浙江联通…