學習springMVC

第四章 Spring MVC

第一節 Spring MVC 簡介

1. Spring MVC

SpringMVC是一個Java 開源框架, 是Spring Framework生態中的一個獨立模塊,它基于 Spring 實現了Web MVC(數據、業務與展現)設計模式的請求驅動類型的輕量級Web框架,為簡化日常開發,提供了很大便利。

2. Spring MVC 核心組件

  • DispatcherServlet 前置控制器

    負責接收請求、分發請求

  • Handler 處理器

    處理器包括了攔截器、控制器中的方法等,主要負責處理請求

  • HandlerMapping 處理器映射器

    解析配置文件、掃描注解,將請求與處理器進行匹配

  • HandlerAdpter 處理器適配器

    根據請求來找到匹配的處理器,這個過程稱為適配

  • ViewResolver 視圖解析器

    處理器執行后得到的結果可能是一個視圖,但這個視圖屬于邏輯視圖(頁面中存在邏輯代碼,比如循環、判斷),需要使用視圖解器行處理,這個過程稱為渲染視圖

第二節 Spring MVC 發展演變

<!--低版本-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.9.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.3.9.RELEASE</version>
</dependency>
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>

1. Bean的名字或ID匹配URL請求

1.1 web.xml 配置
<servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><!--配置Servlet初始化參數--><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><!--前置控制器要接收所有的請求,因此在容器啟動的時候就應該完成初始化--><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>
1.2 spring-mvc.xml 配置
<!--視圖解析器:在控制器返回視圖的時候生效-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--視圖資源的前綴--><property name="prefix" value="/" /><!--視圖資源的后綴--><property name="suffix" value=".jsp" />
</bean>
<!--處理器映射的方式:使用bean的名字或者id的值來與請求匹配-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
1.3 編寫控制器
public class UserController extends AbstractController {@Overrideprotected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {//這里使用配置的視圖解析器進行解析  user => / + user + .jsp => /user.jspreturn new ModelAndView("user");}
}
1.4 配置控制器
<!--通過id值匹配請求的URL-->
<bean id="/view" class="com.qf.spring.mvc.controller.UserController" />

思考:按照這種匹配請求的方式,每一個請求需要一個控制器與之對應,這與使用Servlet開發一樣,會編寫大量的控制器,導致開發效率極為低下,如何解決?

Spring 提供了方法名來匹配請求來解決這個問題

2. Bean的方法名匹配請求

2.1 方法名解析器

Spring 提供了控制器內的方法名的解析器 InternalPathMethodNameResolver,該解析器作用就是將方法名作為匹配URL請求的依據,與控制器關聯起來

2.2 多操作控制器

Spring 提供了 MultiActionController 控制器類,供其他控制器類繼承,在其子類中,開發者可以編寫多個處理請求的方法,然后使用方法名解析器去匹配請求

2.3 編寫控制器
public class UserMultiController extends MultiActionController {//這個方法就匹配 /login 請求//請求格式必須是 //ModelAndView 方法名(HttpServletRequest req, HttpServletResponse resp){}public ModelAndView login(HttpServletRequest req, HttpServletResponse resp){return new ModelAndView("login");}//這個方法就匹配 /register 請求public ModelAndView register(HttpServletRequest req, HttpServletResponse resp){return new ModelAndView("register");}
}
2.4 spring-mvc.xml 配置
 <!--方法名解析器-->
<bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />
<!-- /login 請求使用該bean對象處理-->
<bean id="/login" class="com.qf.spring.mvc.controller.UserMultiController"><property name="methodNameResolver" ref="methodNameResolver" />
</bean>
<!-- /register 請求使用該bean對象處理-->
<bean id="/register" class="com.qf.spring.mvc.controller.UserMultiController"><property name="methodNameResolver" ref="methodNameResolver" />
</bean>

思考:按照這種匹配請求的方式,如果一個控制器要處理多個請求,那么就會導致配置信息繁多的問題,后期難以維護,如何解決?

Spring 提供了 SimpleUrlHandlerMapping 映射器, 該映射器支持一個控制器與多個請求匹配的同時也解決了配置信息繁多的問題。

3. 簡單URL處理器映射

使用SimpleUrlHandlerMapping只需要修改 spring-mvc.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--視圖解析器:在控制器返回視圖的時候生效--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--視圖資源的前綴--><property name="prefix" value="/" /><!--視圖資源的后綴--><property name="suffix" value=".jsp" /></bean><!--處理器映射的方式:使用bean的名字或者id的值來與請求匹配-->
<!--    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>--><!--通過id值匹配請求的URL-->
<!--    <bean id="/view" class="com.qf.spring.mvc.controller.UserController" />--><!--方法名解析器-->
<!--    <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />--><!-- /login 請求使用該bean對象處理-->
<!--    <bean id="/login" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>--><!-- /register 請求使用該bean對象處理-->
<!--    <bean id="/register" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>--><bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props><prop key="/view">userController</prop><prop key="/user/*">userMultiController</prop></props></property></bean><bean id="userController" class="com.qf.spring.mvc.controller.UserController" /><bean id="userMultiController" class="com.qf.spring.mvc.controller.UserMultiController" />
</beans>

思考:隨著項目開發的推進,開發的業務功能越來越多,控制器的數量也會伴隨著增加,請求的匹配同時也會增加,同樣會造成后期難以維護的問題,如何解決呢?

Spring 提供了 DefaultAnnotationHandlerMapping 映射器,支持使用注解來匹配請求,這樣就解決了請求匹配導致配置信息繁多的問題,同時還提升了開發效率。

4. 注解匹配請求

4.1 編寫控制器
@Controller
public class UserAnnotationController {@RequestMapping(value = "/login", method = RequestMethod.GET)public String login(){return "login";}@RequestMapping(value = "/register", method = RequestMethod.GET)public String register(){return "register";}
}
4.2 spring-mvc.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--視圖解析器:在控制器返回視圖的時候生效--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--視圖資源的前綴--><property name="prefix" value="/" /><!--視圖資源的后綴--><property name="suffix" value=".jsp" /></bean><!--處理器映射的方式:使用bean的名字或者id的值來與請求匹配-->
<!--    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>--><!--通過id值匹配請求的URL-->
<!--    <bean id="/view" class="com.qf.spring.mvc.controller.UserController" />--><!--方法名解析器-->
<!--    <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />--><!-- /login 請求使用該bean對象處理-->
<!--    <bean id="/login" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>--><!-- /register 請求使用該bean對象處理-->
<!--    <bean id="/register" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>--><!--<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props><prop key="/view">userController</prop><prop key="/login">userMultiController</prop><prop key="/register">userMultiController</prop></props></property></bean><bean id="userController" class="com.qf.spring.mvc.controller.UserController" /><bean id="userMultiController" class="com.qf.spring.mvc.controller.UserMultiController" />--><!--類上的注解處理器--><bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /><!--方法上的注解處理器--><bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /><!--掃描包,使得該包下類以及類中定義的方法上所使用的注解生效--><context:component-scan base-package="com.qf.spring.mvc.controller" />
</beans>

5. 較新的版本配置

<?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--視圖解析器:在控制器返回視圖的時候生效--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--視圖資源的前綴--><property name="prefix" value="/" /><!--視圖資源的后綴--><property name="suffix" value=".jsp" /></bean><!--較新的版本使用該標簽開啟注解支持--><mvc:annotation-driven /><!--掃描包,使得該包下類以及類中定義的方法上所使用的注解生效--><context:component-scan base-package="com.qf.spring.mvc.controller" />
</beans>

第三節 Spring MVC 常用注解

1. @Controller

該注解是一個控制器的標識

@Controller
public class UserController{}

2. @RequestMapping

該注解用于匹配請求

@Controller
@RequestMapping("/user")
public class UserController{@RequestMapping(value="/login", method=RequestMethod.POST)public int login(){return 1;}
}

3. @RequestBody

該注解只能應用在方法的參數上,用于從請求體中獲取數據并注入至參數中

@Controller
@RequestMapping("/user")
public class UserController{@RequestMapping(value="/login", method=RequestMethod.POST)public int login(@RequestBody User user){return 1;}
}

4. @ResponseBody

該注解用于向頁面傳遞數據

@Controller
@RequestMapping("/user")
public class UserController{@RequestMapping(value="/login", method=RequestMethod.POST)@ResponseBodypublic int login(@RequestBody User user){return 1;}
}

5. @RequestParam

該注解只能應用在方法的參數上,用于從請求頭中獲取數據并注入至參數中

@Controller
@RequestMapping("/user")
public class UserController{@RequestMapping(value="/search", method=RequestMethod.GET)@ResponseBodypublic List<User> searchUsers(@RequestParam(value="name") String name){return new ArrayList<>();}
}

6. @PathVariable

該注解只能應用在方法的參數上,用于從請求路徑中獲取數據并注入至參數中

@Controller
@RequestMapping("/user")
public class UserController{// /user/admin@RequestMapping(value="/{username}", method=RequestMethod.GET)@ResponseBodypublic User queryUser(@PathVariable("username") String username){return new User();}
}

7. @SessionAttributes[不重要]

該注解只能使用在類定義上,用于從將輸入放入 session 中

@SessionAttributes(types=User.class) //會將model中所有類型為 User的屬性添加到會話中。
@SessionAttributes(value={“user1”, “user2”}) //會將model中屬性名為user1和user2的屬性添加到會話中。
@SessionAttributes(types={User.class, Dept.class}) //會將model中所有類型為 User和Dept的屬性添加到會話中。
@SessionAttributes(value={“user1”,“user2”},types={Dept.class}) //會將model中屬性名為user1和user2以及類型為Dept的屬性添加到會話中。

8. @RequestHeader

該注解只能應用在方法的參數上,用于從請求頭中獲取數據

@RequestMapping("/find")  
public void findUsers(@RequestHeader("Content-Type") String contentType) {//從請求頭中獲取Content-Type的值
}  

9. @CookieValue

該注解只能應用在方法的參數上,用于從請求中獲取cookie的值

@RequestMapping("/find")  
public void findUsers(@CookieValue("JSESSIONID") String jsessionId) {//從請cookie中獲取jsessionId的值
}  

10. @ControllerAdvice

該注解只能應用在類上,表示這個類就是處理異常的控制器

/*** 異常處理的控制器*/
@ControllerAdvice //這個注解就是spring mvc提供出來做全局異常統一處理的
public class ExceptionController {
}

11. @ExceptionHandler

該注解只能應用在@ControllerAdvice或者說@RestControllerAdvice標識的類的方法上,用來處理異常

/*** 異常處理的控制器*/
@ControllerAdvice //這個注解就是spring mvc提供出來做全局異常統一處理的
public class ExceptionController {@ExceptionHandler //異常處理器@ResponseBody //響應至頁面public String handleException(Exception e){return e.getMessage();}
}

第四節 JSR-303

1. JSR-303 簡介

JSR全稱為 Java Specification Requests,表示 Java 規范提案。JSR-303是 Java 為 Java Bean 數據合法性校驗提供的標準框架,它定義了一套可標注在成員變量,屬性方法上的校驗注解。Hibernate Validatior提供了這套標準的實現。

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>6.0.1.Final</version><!-- 最新7.0.1.Final -->
</dependency>

2. 校驗注解

注解解釋注解解釋
@Null必須為null@NotNull不能為null
@AssertTrue必須為true@AssertFalse必須為false
@Min必須為數字,其值大于或等于指定的最小值@Max必須為數字,其值小于或等于指定的最大值
@DecimalMin必須為數字,其值大于或等于指定的最小值@DecimalMax必須為數字,其值小于或等于指定的最大值
@Size集合的長度@Digits必須為數字,其值必須再可接受的范圍內
@Past必須是過去的日期@Future必須是將來的日期
@Pattern必須符合正則表達式@Email必須是郵箱格式
@Length(min=,max=)字符串的大小必須在指定的范圍內@NotEmpty不能為null,長度大于0
@Range(min=,max=,message=)元素必須在合適的范圍內@NotBlank不能為null,字符串長度大于0(限字符串)

3. 應用

<dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>5.3.10</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.10</version>
</dependency>
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>6.0.1.Final</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.78</version>
</dependency>
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope>
</dependency>
<!-- web.xml -->
<servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>
<?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:p="http://www.springframework.org/schema/p"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" /><mvc:annotation-driven><mvc:message-converters><!--處理字符串的消息轉換器--><bean class="org.springframework.http.converter.StringHttpMessageConverter" /><!--處理JSON格式的消息轉換器--><bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json;charset=UTF-8</value></list></property></bean></mvc:message-converters></mvc:annotation-driven><context:component-scan base-package="com.qf.spring.controller" />
</beans>
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;import javax.validation.constraints.NotNull;public class User {@NotNull(message = "賬號不能為空")@Length(min = 8, max = 15, message = "賬號長度必須為8~15位")private String username;@NotNull(message = "密碼不能為空")@Length(min = 8, max = 20, message = "密碼長度必須為8~20位")private String password;@Range(min = 0, max = 120, message = "年齡只能在0~120歲之間")private int age;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.validation.Valid;@Controller
@RequestMapping("/user")
public class UserController {@RequestMapping("/add")@ResponseBodypublic Object saveUser(@Valid User user, BindingResult result){if(result.hasErrors()) return result.getAllErrors();return 1;}
}

第五節 RESTFUL

1. RESTFUL 簡介

REST全稱為 Representational State Transfer,表示 表述性狀態轉移

RESTFUL有如下特點:

  • 每一個 URI 代表一種資源
  • 客戶端使用GET、POST、PUT、DELETE4 個表示操作方式的動詞對服務端資源進行操作:GET用來獲取資源,POST用來新建資源(也可以用于更新資源),PUT用來更新資源,DELETE用來刪除資源

2. RESTFUL 請求

/user GET => 獲取用戶資源
/user POST => 增加用戶資源
/user PUT => 修改用戶資源
/user DELETE => 刪除用戶資源/user/{username} GET => 獲取指定用戶資源  這是RESTFUL風格中子資源的表述方式

3. Spring 對 RESTFUL 的支持

3.1 @RestController

該注解只能應用于類上,相當于@Controller 和 @ResponseBody 注解的組合。表示該類中的所有方法執行完成后所返回的結果直接向頁面輸出

3.2 @GetMapping
3.2 @PostMapping
3.2 @PutMapping
3.2 @DeleteMapping

第六節 靜態資源處理

1. 靜態資源無法訪問的原因

靜態資源包含html、js、css、圖片、字體文件等。靜態文件沒有url-pattern,所以默認是訪問不到的。之所以可以訪問,是因為tomcat中有一個全局的servlet:org.apache.catalina.servlets.DefaultServlet,它的url-pattern是 “/”, 所以項目中不能匹配的靜態資源請求,都由這個Servlet來處理。但在SpringMVC中DispatcherServlet也采用了"/" 作為url-pattern, 那么項目中不會再使用全局的Serlvet,這樣就造成了靜態資源不能完成訪問。

2. 處理方案

2.1 方案一

DispathcerServlet 對應的 url-pattern 修改為 “/” 以外的其他匹配樣式即可。比如 *.do, *.action。這樣修改后,發送請求時,請求URL必須匹配 .do 或者 .action。

2.2 方案二
<!-- web.xml -->
<servlet-mapping><servlet-name>default</servlet-name><url-pattern>/static/*</url-pattern></servlet-mapping>
2.2 方案三
<!-- spring-mvc.xml -->
<!-- 
這個handler就是處理靜態資源的,它的處理方式就是將請求轉會到tomcat中名為default的Servlet 
-->
<mvc:default-servlet-handler/>
<!-- mapping是訪問路徑,location是靜態資源存放的路徑 -->
<mvc:resources mapping="/static/**" location="/static/" />

第七節 中文亂碼處理

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><filter><filter-name>encodingFilter</filter-name><!--字符編碼過濾器--><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><!--編碼格式--><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><!--強制編碼--><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

第八節 Spring MVC工作原理

checkMultipart(request); //檢測是否是多部分請求,這個只可能在文件上傳的時候為真getHandler(processedRequest); //獲取處理器 => 遍歷HandlerMapping,找到匹配當前請求的執行器鏈
//沒有找到執行器鏈 就直接向頁面報一個404
noHandlerFound(processedRequest, response);
//找到處理當前請求的適配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//控制器之前執行的攔截器將先執行,如果攔截器不通過,則方法直接結束
if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;
}
//控制器處理請求,可能會得到一個ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//控制器之后的攔截器執行
mappedHandler.applyPostHandle(processedRequest, response, mv);
//處理分發的結果:這個結果就是控制器處理后的結果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
//攔截器在控制器給出的結果DispatcherServlet處理后執行
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39627.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39627.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39627.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

車云匯的元宇宙之旅

在汽車行業持續迎來數字化和科技革新的今天&#xff0c;車云匯作為一個領先的汽車服務平臺&#xff0c;正通過探索元宇宙這一新興概念&#xff0c;將傳統服務與虛擬現實技術相結合&#xff0c;為車主提供全新的互動體驗和服務模式。這一創新不僅有望改變汽車行業的服務面貌&…

匿名內部類在Java編程中的應用與限制

匿名內部類在Java編程中的應用與限制 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 匿名內部類在Java編程中的應用與限制 1. 什么是匿名內部類&#xff1f;…

什么叫創世區塊、創世區塊有什么用、為什么需要創世區塊

創世區塊&#xff08;Genesis Block&#xff09;是任何區塊鏈技術中的第一個區塊&#xff0c;它是區塊鏈的起點&#xff0c;標志著該區塊鏈的誕生。在創世區塊之前沒有任何區塊存在&#xff0c;因此它沒有前一個區塊的哈希值&#xff0c;通常這個位置會被設置為零或者一個預定義…

vue3源碼(六)渲染原理-runtime-dom

1、從入口文件看實現 項目入口文件 import { createApp } from vue import ./style.css import App from ./App.vuecreateApp(App).mount(#app)文件位置core\packages\runtime-dom\src\index.ts 保證了render的唯一性 // // rendererOptions 是patchProp 和nodeOps的合集&a…

可視化低代碼平臺之:RayData光啟元的震撼作品。

RayData家的可視化作品&#xff0c;貝格前端工場是經常碰到&#xff0c;制作十分的精良&#xff0c;業內很有影響力。他們也有自己的低代碼平臺&#xff0c;分為了桌面版和網頁版&#xff0c;本期分享一下他們的作品。

徹底掌握 Git:從零基礎到高級實戰的全方位教程

文章目錄 一、Git 簡介二、安裝 Git1. Windows2. macOS3. Linux 三、Git 基本概念四、初次使用 Git1. 配置 Git2. 創建一個新的 Git 倉庫3. 克隆一個遠程倉庫4. 跟蹤文件5. 提交變更6. 查看歷史記錄 五、Git 分支管理1. 創建和切換分支2. 合并分支3. 分支沖突 六、遠程倉庫1. 添…

to_json 出現亂碼的解決方案

大家好,我是愛編程的喵喵。雙985碩士畢業,現擔任全棧工程師一職,熱衷于將數據思維應用到工作與生活中。從事機器學習以及相關的前后端開發工作。曾在阿里云、科大訊飛、CCF等比賽獲得多次Top名次。現為CSDN博客專家、人工智能領域優質創作者。喜歡通過博客創作的方式對所學的…

國產分布式數據庫災備高可用實現

最近在進行核心業務系統的切換演練測試&#xff0c;就在想一個最佳的分布式數據庫高可用部署方案是如何保證數據不丟、系統可用的&#xff0c;做到故障時候可切換、可回切&#xff0c;并且業務數據的一致性。本文簡要介紹了OceanBase數據庫和GoldenDB數據庫在災備高可用的部署方…

kafka的架構

一、架構圖 Broker&#xff1a;一臺 kafka 服務器就是一個 broker。一個kakfa集群由多個 broker 組成。一個 broker 可以容納多個 topic。 Producer&#xff1a;消息生產者&#xff0c;就是向 kafka broker 發消息的客戶端 Consumer&#xff1a;消息消費者&#xff0c;向 kafk…

深海電波,智能駕馭:海上發電系統中的先進網關技術

隨著技術的不斷演進&#xff0c;海上風電場逐漸走向深海&#xff0c;隨之而來的高速通信保障成為一大難題。同時&#xff0c;海上風電特殊的環境與部署技術&#xff0c;也給運維帶來了作業難、成本高、響應慢等困難。通過在沿海岸邊建立高站&#xff0c;結合超遠覆蓋、載波聚合…

springboot java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver 應該如何解決

遇到的問題&#xff1a;項目中引用了外部的達夢jar包 在idea中正常使用 也能找到dm.jdbc.driver.DmDriver 驅動 但是當通過jenkins 構建部署到服務器上 總是報 ClassNotFoundException: dm.jdbc.driver.DmDriver 找不到驅動 應用到的驅動代碼如下格式 排查步驟 1.首先看你的項…

ROS2仿真工具-gazebo

gazebo獨立于ROS2&#xff0c;就像插件一樣&#xff0c;需要安裝。 1.安裝 sudo apt install gazebo sudo apt install ros-humble-gazebo-* 2.運行測試demo gazebo /opt/ros/humble/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world 查看所有話題 ros2 top…

0052__windows下實現socketpair函數

windows下實現socketpair函數_socketpair windows 實現-CSDN博客 socketpair函數介紹及使用-CSDN博客

使用css做一個旋轉的八卦圖

使用css做一個旋轉的八卦圖 1, html部分 <div class"tai"><div class"bai"></div><div class"hei"></div> </div>2, css部分 .tai{width: 200px;height: 200px;border: 1px solid #000;background: linea…

工業路由器的應用

上文講了工業路由器與家用路由器的區別, 家用路由器的使用場景想必大家都不陌生&#xff0c;那么工業路由器可以具體應用在哪些領域呢&#xff1f; 工業路由器憑借其多接口、多協議、寬溫寬壓等工業設計特性&#xff0c;可以廣泛應用于各類工業化場景&#xff0c;為各類工業傳…

STM32中的I2S(Inter-IC Sound)接口和SA接口(Serial Audio Interface)的區別

STM32中的I2S&#xff08;Inter-IC Sound&#xff09;接口和SA接口&#xff08;這里的SA可能指的是SAI&#xff0c;Serial Audio Interface&#xff09;雖然都用于音頻數據傳輸&#xff0c;但它們在設計目標、功能特性和應用場景上存在一些區別&#xff1a; I2S (Inter-IC Sou…

STM32-I2C硬件外設

本博文建議與我上一篇I2C 通信協議??????共同理解 合成一套關于I2C軟硬件體系 STM32內部集成了硬件I2C收發電路&#xff0c;可以由硬件自動執行時鐘生成、起始終止條件生成、應答位收發、數據收發等功能&#xff0c;減輕CPU的負擔 特點&#xff1a; 多主機功能&#x…

Shiro框架

入門概述 1 shiro是什么? Apache Shiro 是一個功能強大且易于使用的 Java 安全(權限)框架。Shiro 可以完成&#xff1a;認證、授權、加密、會話管理、與 Web 集成、緩存 等。借助 Shiro 您可以快速輕松地保護任何應用程序——從最小的移動應用程序到最大的 Web 和企業應用程…

計算機網絡網絡層復習題1

一. 單選題&#xff08;共27題&#xff09; 1. (單選題)以太網 MAC 地址、IPv4 地址、IPv6 地址的地址空間大小分別是&#xff08; &#xff09;。 A. 2^48&#xff0c;2^32&#xff0c;2^128B. 2^32&#xff0c;2^32&#xff0c;2^96C. 2^16&#xff0c;2^56&#xff0c;2^6…

選對箱式壓風自救裝置提升煤礦生產效率

選對箱式壓風自救裝置提升煤礦生產效率&#xff0c;安全是煤礦穩定生產的基石&#xff0c;只有始終保持對安全的敬畏之心&#xff0c;才能確保礦區可持續發展和經濟效益的穩步提升。 150簡介 ZYJ-A型礦井壓風自救裝置是煤礦煤塵、瓦斯和二氧化碳突出礦井的實際情況&#xff0c…