兄弟萌,這份SpringMVC框架學(xué)習(xí)筆記真的建議反復(fù)看,寫(xiě)的太細(xì)了

概述

  • 是Spring為展現(xiàn)層提供的基于MVC設(shè)計(jì)理念的Web框架,通過(guò)一套MVC注解,讓POJO成為處理請(qǐng)求的控制器,而無(wú)需實(shí)現(xiàn)任何接口
  • 支持REST風(fēng)格的URL請(qǐng)求
  • 采用松散耦合的可插拔組件結(jié)構(gòu),比其他MVC框架更具擴(kuò)展性和靈活性
  • SpringMVC的IOC容器是Spring的IOC容器的子容器,故而可引用Spring的IOC中的bean,反之則不行

運(yùn)行流程

  • 當(dāng)前端發(fā)出請(qǐng)求時(shí),首先進(jìn)入到DispatcherServlet(中央控制器),把請(qǐng)求的地址傳給HandlerMapping處理器映射器中進(jìn)行比對(duì)(Handler即包含了我們請(qǐng)求的Controller類(lèi)和Method方法的對(duì)象)
  • 未找到則表示靜態(tài)資源,進(jìn)入defaultServlet處理器,返回前端
  • 找到則表示動(dòng)態(tài)資源,調(diào)用AdapterMap數(shù)據(jù)適配器,獲取該資源的執(zhí)行列表(目標(biāo)方法,攔截器方法),并返回處理器執(zhí)行鏈(HandlerExecutionChain)給中央控制器
  • 中央控制器將結(jié)果交給HandlerAdapter處理器適配器,依次執(zhí)行執(zhí)行列表的方法,返回邏輯視圖ModelAndView給中央控制器
  • 將結(jié)果交給ViewResolver視圖解析器,遍歷生成具體的View物理視圖
  • 中央控制器調(diào)用render方法渲染視圖,即將數(shù)據(jù)文件轉(zhuǎn)化成可視化界面返回前端

步驟

  • 導(dǎo)入jar包,在web.xml中配置中央控制器DispatcherServlet,加入SpringMVC配置文件
<servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置中央控制器的初始化參數(shù):配置文件的位置和名稱(chēng) -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!-- 默認(rèn)為WEB-INF/<servlet-name>-servlet.xml -->
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <!-- 配置servlet被加載的先后順序 -->
        <!-- 為負(fù)數(shù)或者沒(méi)有設(shè)置,則容器會(huì)當(dāng)Servlet被請(qǐng)求時(shí)再加載 -->
        <!-- 為正整數(shù)或者0時(shí),表示容器在應(yīng)用啟動(dòng)時(shí)就加載并初始化這個(gè)servlet -->
        <!-- 值越小,servlet的優(yōu)先級(jí)越高,就越先被加載。值相同時(shí),容器就會(huì)自己選擇順序來(lái)加載 -->
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>

  • 編寫(xiě)處理請(qǐng)求的處理器并標(biāo)識(shí)@Controller,編寫(xiě)視圖
  • 使用@RequestMapping("/地址") //映射請(qǐng)求的URL,可放在類(lèi)與方法上,方法返回值進(jìn)入視圖解析器(使用@GetMapping("/地址")響應(yīng)get請(qǐng)求,@PostMapping("/地址")響應(yīng)post請(qǐng)求)
<!--注解驅(qū)動(dòng),以使得訪問(wèn)路徑與方法的匹配可以通過(guò)注解配置-->
<mvc:annotation-driven />
<!-- 在配置dispatchServlet時(shí)配置<url-pattern>/</url-pattern>攔截所有請(qǐng)求,這時(shí)候dispatchServlet完全取代了default servlet,將不會(huì)再訪問(wèn)容器中原始默認(rèn)的servlet,而對(duì)靜態(tài)資源的訪問(wèn)就是通過(guò)容器默認(rèn)servlet處理的,故而這時(shí)候靜態(tài)資源將不可訪問(wèn),使用下列標(biāo)簽訪問(wèn)靜態(tài)資源 -->
<mvc:default-servlet-handler/>

  • 在SpringMVC配置文件中配置要掃描的包,配置視圖解析器
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/響應(yīng)地址前綴/"></property>
        <property name="suffix" value=".后綴"></property>
</bean>

REST

  • 資源表現(xiàn)層狀態(tài)轉(zhuǎn)換,是一種互聯(lián)網(wǎng)軟件架構(gòu)
  • 資源:網(wǎng)絡(luò)上的一個(gè)實(shí)體即一個(gè)具體信息,可為一段文字,一張圖片,一種服務(wù),總之是一個(gè)具體的存在,可以用URI指向它,每種資源對(duì)應(yīng)一個(gè)特定的URI,訪問(wèn)URI可獲取這個(gè)資源
  • 表現(xiàn)層:把資源具體呈現(xiàn)出來(lái)的形式,就為表現(xiàn)層,如txt、json、html、二進(jìn)制等
  • 狀態(tài)轉(zhuǎn)化:每發(fā)出一次請(qǐng)求,就代表客戶端和服務(wù)器的一次交互過(guò)程,http為無(wú)狀態(tài)協(xié)議,所有的狀態(tài)保存在服務(wù)器中,因此要想操作服務(wù)器,必須通過(guò)某種手段,讓服務(wù)器發(fā)生狀態(tài)轉(zhuǎn)化。Http協(xié)議里有四種基本操作:GET用來(lái)獲取資源,POST用來(lái)新建資源,PUT用來(lái)更新資源,DELETE用來(lái)刪除資源

注解

  • @RequestMapping

    • 為控制器指定可處理那些請(qǐng)求,進(jìn)而確定執(zhí)行那個(gè)方法
    • 定義類(lèi)上:提供初步的請(qǐng)求映射信息
    • 定義方法上:提供細(xì)分的映射信息
    • 屬性
      • value:請(qǐng)求url
      • method:請(qǐng)求方法(RequestMethod.get,RequestMethod.post)多值用數(shù)組
      • params:請(qǐng)求參數(shù)
        • 值可使用簡(jiǎn)單表達(dá)式,例!p表示請(qǐng)求參數(shù)不能包含p
        • params={“name”,“age!=10”} 參數(shù)age不為10
      • heads:請(qǐng)求頭
        • 值可使用簡(jiǎn)單表達(dá)式,heads={“Accept-Language=en-US,zh”}
      • 可聯(lián)合使用,使請(qǐng)求更加精確化
    • 支持Ant風(fēng)格匹配符
      • 匹配文件名中的一個(gè)字符 ?
      • 匹配文件名中的任意字符 *
      • 匹配多層路徑 **
    • @PathVariable 用來(lái)將URL中的占位符參數(shù)綁定到目標(biāo)方法的參數(shù)中
      • @RequestMapping("/a/{id}")
        • @PathVariable(“id”)
    • HiddenHttpMethodFilter 過(guò)濾器將請(qǐng)求轉(zhuǎn)換為標(biāo)準(zhǔn)的http方法,使瀏覽器form表單支持put,delete請(qǐng)求
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    
    • CharacterEncodingFilter 過(guò)濾器用于處理中文
    <filter>
        <filter-name>CharacterEncodingFilter</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>
    </filter>
    <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    
  • @RequestParam

    • 用來(lái)映射url中請(qǐng)求參數(shù)
    • 定義在方法形參前,給形參賦值
    • 屬性
      • value:請(qǐng)求參數(shù)的參數(shù)名
      • required:該參數(shù)是否必須,默認(rèn)為true
      • defaultValue:請(qǐng)求參數(shù)默認(rèn)值
  • @RequestHeader

    • 映射請(qǐng)求頭信息
    • 將請(qǐng)求報(bào)頭的屬性值綁定到處理方法的形參中
    • 請(qǐng)求頭包含若干屬性,服務(wù)器可據(jù)此獲知客戶端信息
    • 屬性
      • value:請(qǐng)求頭參數(shù)的參數(shù)名
  • @CookieValue

    • 映射Cookie信息
    • 屬性與RequestParam相同
  • @ResponseBody

    • 標(biāo)注在方法上
    • 將java對(duì)象轉(zhuǎn)為json格式的數(shù)據(jù)
    • 將controller的方法返回的對(duì)象通過(guò)適當(dāng)?shù)霓D(zhuǎn)換器轉(zhuǎn)換為指定的格式之后,寫(xiě)入到response對(duì)象的body區(qū),通常用來(lái)返回JSON或XML數(shù)據(jù)(用于異步獲取數(shù)據(jù))
    • 在使用此注解之后不會(huì)再走視圖處理器,而是直接將數(shù)據(jù)寫(xiě)入到輸入流中,他的效果等同于通過(guò)response對(duì)象輸出指定格式的數(shù)據(jù)
    • 所需jar包:jackson-annotations-2.9.0.pr2.jar,jackson-core-2.9.0.pr2.jar,jackson-databind-2.9.0.pr2.jar
    • 使用fastJSON.jar 對(duì)象轉(zhuǎn)json:JSON.toJSONString(對(duì)象)
    • 使用fastJSON.jar json轉(zhuǎn)對(duì)象:JSON.parseObject(json,對(duì)象.class)
  • @RequestBody

    • 標(biāo)注在形參上
    • 將前臺(tái)發(fā)送過(guò)來(lái)的JSON或XML數(shù)據(jù)封裝為對(duì)應(yīng)的 JavaBean 對(duì)象,封裝時(shí)使用到的一個(gè)對(duì)象是系統(tǒng)默認(rèn)配置的 HttpMessageConverter 進(jìn)行解析,然后封裝到形參上
    • GET、POST方式提交
      • 表單屬性 enctype
        • 可選 application/x-www-form-urlencoded
        • 不能處理 multipart/form-data 格式的數(shù)據(jù)
        • 必須 application/json,application/xml 格式的數(shù)據(jù)
    • PUT方式提交
      • 表單屬性 enctype
        • 必須 application/x-www-form-urlencoded
        • 不能處理 multipart/form-data 格式的數(shù)據(jù)
  • @initBinder

    • 提供數(shù)據(jù)綁定,可對(duì)WebDataBinder對(duì)象進(jìn)行初始化
    • 標(biāo)注方法不能有返回值
  • @NumberFormat

    • 對(duì)數(shù)字類(lèi)型的屬性格式化
  • @DateTimeFormat

    • 對(duì)日期類(lèi)型屬性格式化
    • pattern屬性:yyyy-MM-dd hh:mm:ss

處理器參數(shù)

POJO
  • 普通Java類(lèi),具有一部分getter/setter方法的那種類(lèi)就可以稱(chēng)作POJO,實(shí)際意義就是普通的JavaBeans(簡(jiǎn)單的實(shí)體類(lèi)),特點(diǎn)就是支持業(yè)務(wù)邏輯的協(xié)助類(lèi)
  • SpringMVC會(huì)按請(qǐng)求參數(shù)名與pojo屬性名進(jìn)行自動(dòng)匹配,自動(dòng)填充屬性值。且支持級(jí)聯(lián)屬性
servlet原生API
  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale
  • InputStream
  • OutputStream
  • Reader
  • Writer

處理器處理模型數(shù)據(jù)

Map,Model或ModelMap類(lèi)型
  • 使用org.springframework.ui.Model接口存儲(chǔ)模型數(shù)據(jù)
  • 過(guò)程:在調(diào)用方法前會(huì)創(chuàng)建一個(gè)隱含的模型對(duì)象作為存儲(chǔ)容器,如果參數(shù)是Map或Model類(lèi)型,則將模型的引用傳遞給參數(shù),從而通過(guò)參數(shù)對(duì)象訪問(wèn)模型中的數(shù)據(jù)或向模型中添加新屬性數(shù)據(jù)
  • 添加Map.put(“對(duì)象名”,對(duì)象值)、Model.addAttribute(“對(duì)象名”,對(duì)象值)
  • 返回String類(lèi)型
ModelAndView類(lèi)型
  • 包含視圖與模型信息
  • ModelAndView ret = new ModelAndView(); //實(shí)例化
  • ret.add(“對(duì)象名”,對(duì)象值) //添加數(shù)據(jù)到ModelAndView中
  • SpringMVC會(huì)把ModelAndView的Model中的數(shù)據(jù)放到request域?qū)ο笾?/li>
  • 返回ModelAndView類(lèi)型
@SessionAttributes
  • 用于在多個(gè)請(qǐng)求之間公用某個(gè)模型屬性數(shù)據(jù)
  • 標(biāo)注在控制器類(lèi)上,使屬性暫存在HttpSession中,屬性就可在session中獲取
  • 屬性
    • value={屬性名}
    • types={屬性類(lèi)型.class}
@ModelAttribute
  • 標(biāo)注在方法上,使每個(gè)目標(biāo)方法執(zhí)行之前被SpringMVC調(diào)用將標(biāo)注方法的屬性賦值給對(duì)應(yīng)參數(shù)
  • 標(biāo)注在pojo類(lèi)型形參前,使形參為被@ModelAttribute標(biāo)注的方法的屬性
  • 注:在標(biāo)注方法中放入map中的鍵與目標(biāo)方法形參一致(首字母小寫(xiě))

視圖解析器

  • 對(duì)于返回String,View,ModeMap等類(lèi)型,SpringMVC會(huì)在內(nèi)部將它們裝配成一個(gè)ModelAndView對(duì)象,包含邏輯名和模型對(duì)象的視圖,借助視圖解析器最終得到視圖對(duì)象View
  • 視圖的作用是渲染模型數(shù)據(jù),將模型里的數(shù)據(jù)以某種形式呈現(xiàn)給客戶
  • 視圖對(duì)象由視圖解析器負(fù)責(zé)實(shí)例化。由于視圖是無(wú)狀態(tài)的,所以他們不會(huì)有線程安全的問(wèn)題。所謂視圖是無(wú)狀態(tài)的,是指對(duì)于每一個(gè)請(qǐng)求,都會(huì)創(chuàng)建一個(gè)View對(duì)象
  • JSP是最常見(jiàn)的視圖技術(shù),結(jié)合JSTL使用
  • 常用視圖解析器實(shí)現(xiàn)類(lèi)
    • BeanNameViewResolver:將邏輯視圖解析為一個(gè)bean,bean的id等于邏輯視圖名,自動(dòng)根據(jù)我們的視圖名找到對(duì)應(yīng)的視圖Bean進(jìn)行解析
    • InternalResourceViewResolver:將視圖名解析為一個(gè)url文件,會(huì)把 Controller 處理器方法返回的模型屬性都存放到對(duì)應(yīng)的 request 屬性中,然后通過(guò) RequestDispatcher 在服務(wù)器端把請(qǐng)求 forword 重定向到目標(biāo) URL
    • 多個(gè)解析器可通過(guò)order屬性來(lái)指定優(yōu)先級(jí),越小優(yōu)先級(jí)越高

轉(zhuǎn)向與重定向

  • 一般情況下控制器方法返回字符串類(lèi)型的值會(huì)被視圖解析器處理
  • 若返回字符串帶有前綴,則做特殊處理,把其后字符串作為url
  • 重定向:在返回值前加redirect:
  • 轉(zhuǎn)向:在返回值前加forward:

配置文件標(biāo)簽

  • <mvc:annotation-driven/> //注解驅(qū)動(dòng)
    • 自動(dòng)注冊(cè) RequestMappingHandlerMapping,RequestMappingHandlerAdapter 與 ExceptionHandlerExceptionResolver 三個(gè)bean(3.1以上)
    • 自動(dòng)為我們將掃描到的@Component,@Controller,@Service,@Repository等注解標(biāo)記的組件注冊(cè)到工廠中,來(lái)處理我們的請(qǐng)求,而<context:component-scan/>標(biāo)簽是告訴Spring 來(lái)掃描指定包下的類(lèi),并注冊(cè)被上述注解標(biāo)記的組件
  • <mvc:default-servlet-handler/>
    • 會(huì)在Spring MVC上下文中定義一個(gè)org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它會(huì)像一個(gè)檢查員,對(duì)進(jìn)入DispatcherServlet的URL進(jìn)行篩查,如果發(fā)現(xiàn)是靜態(tài)資源的請(qǐng)求,就將該請(qǐng)求轉(zhuǎn)由Web應(yīng)用服務(wù)器默認(rèn)的Servlet處理,如果不是靜態(tài)資源的請(qǐng)求,才由DispatcherServlet繼續(xù)處理
    • 一般Web應(yīng)用服務(wù)器默認(rèn)的Servlet名稱(chēng)是"default",因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web應(yīng)用服務(wù)器的默認(rèn)Servlet名稱(chēng)不是"default",則需要通過(guò)default-servlet-name屬性顯示指定
  • <mvc:view-controller>
    • 發(fā)送的請(qǐng)求不想通過(guò)controller,只想直接地跳轉(zhuǎn)到目標(biāo)頁(yè)面
    • path=“訪問(wèn)的路徑”(相當(dāng)于RequestMapping(“訪問(wèn)的路徑”))
    • view-name=“跳轉(zhuǎn)的視圖” (相當(dāng)于return “跳轉(zhuǎn)的視圖”)
    • 必須配置 <mvc:annotation-driven />
    • 與處理器相同則失效

文件上傳

  • 所需jar包:commons-fileupload-1.3.2.jar,commons-io-2.5.jar

  • SpringMVC通過(guò)即插即用的MultipartResolver接口實(shí)現(xiàn),實(shí)現(xiàn)類(lèi)為CommonsMultipartResolver

  • CommonsMultipartResolver配置

    • defaultEncoding必須與jsp頁(yè)面pageEncoding屬性一致
    • jsp頁(yè)面表單屬性enctype 必須 enctype=“multipart/form-data”
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
        <!--文件大小限定-->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>
    
    
  • controller層形參類(lèi)型為MultipartResolver

  • 獲取上傳文件名方法:getOriginalFilename()

  • 獲取文件輸入流:getInputStream()

  • 將文件寫(xiě)入磁盤(pán):transferTo(路徑)

  • 獲取隨機(jī)數(shù) UUID uuid=UUID.randomUUID()

  • 定義為上傳文件名String filePreName=uuid.toString().replaceAll("-", “”)

文件下載

  • 1.可通過(guò)鏈接直接下載特定的后綴的文件
  • 2.通過(guò)附件方式
    • 創(chuàng)建一個(gè)文件輸入流 InputStream is=new FileInputStream(文件路徑)
    • 轉(zhuǎn)成字符數(shù)組 byte[] data=new byte[is.available()]
    • 寫(xiě)入流 is.read(data);
    • 實(shí)例化頭部對(duì)象 HttpHeaders headers=new HttpHeaders()
    • 轉(zhuǎn)碼 String name=new String(readFileName.getBytes(“UTF-8”),“ISO8859-1”)
    • 設(shè)置附件 headers.setContentDispositionFormData(“attachment”, name)
    • 設(shè)置資源類(lèi)型headers.setContentType(MediaType.APPLICATION_OCTET_STREAM)
    • 數(shù)據(jù)加入到附件中 ResponseEntity<byte[]> entity=new ResponseEntity<byte[]>(data, headers, HttpStatus.OK)

攔截器

  • 與過(guò)濾器不同的是攔截器攔截動(dòng)態(tài)資源,即所有被@RequestMapping,@GetMapping ,@PostMapping標(biāo)注的資源
  • 實(shí)現(xiàn)HandlerInterceptor接口
    • public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) //目標(biāo)方法之前執(zhí)行,返回true表示放行
    • public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) //目標(biāo)方法執(zhí)行結(jié)束之后執(zhí)行
    • public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) //頁(yè)面銷(xiāo)毀時(shí)執(zhí)行
  • 攔截器配置
<mvc:interceptors>
    <!--自定義攔截器-->
    <bean class="攔截器類(lèi)路徑"></bean>
    <!--選擇攔截-->
    <mvc:interceptor>
        <!--攔截路徑,**代表路徑及子路徑-->
        <mvc:mapping path="/**"/>
        <!--不攔截路徑-->
        <mvc:exclude-mapping path="/路徑"/>
        <bean class="攔截器類(lèi)路徑"></bean>
    </mvc:interceptor>
</mvc:interceptors>

異常處理

  • 通過(guò)HandlerExceptionResolver接口處理異常,包括Handler映射,數(shù)據(jù)綁定以及目標(biāo)方法執(zhí)行發(fā)生的異常
  • ExceptionHandlerExceptionResolver實(shí)現(xiàn)類(lèi)通過(guò)<mvc:annotation-driven/>加載
    • @ControllerAdvice //標(biāo)注在自定義處理異常類(lèi)上
      • 先找當(dāng)前Handler中的@ExceptionHandler,若未找到匹配的異常類(lèi),則去ControllerAdvice標(biāo)記的類(lèi)中查找
    • @ExceptionHandler({異常類(lèi).class}) //標(biāo)注在異常方法上發(fā)生此異常類(lèi)自動(dòng)執(zhí)行方法處理異常,處理內(nèi)部異常
  • ResponseStatusExceptionResolver實(shí)現(xiàn)類(lèi)
    • @ResponseStatus //標(biāo)注在繼承此類(lèi)的類(lèi)上或發(fā)生異常的方法上
      • value:狀態(tài)碼
      • reason:信息
  • DefaultHandlerExceptionResolver實(shí)現(xiàn)類(lèi)處理特殊異常,例請(qǐng)求方法異常
  • SimpleMappingExceptionResolver實(shí)現(xiàn)類(lèi)
    • 可將不同的異常映射到不同的jsp頁(yè)面(通過(guò)exceptionMappings屬性的配置),同時(shí)我們也可以為所有的異常指定一個(gè)默認(rèn)的異常
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
    <!-- 定義默認(rèn)的異常處理頁(yè)面,當(dāng)該異常類(lèi)型的注冊(cè)時(shí)使用 -->  
    <property name="defaultErrorView" value="error"></property>  
    <!-- 定義異常處理頁(yè)面用來(lái)獲取異常信息的變量名,默認(rèn)名為exception -->  
    <property name="exceptionAttribute" value="ex"></property>  
    <!-- 定義需要特殊處理的異常,用類(lèi)名或完全路徑名作為key,異常也頁(yè)名作為值 -->  
    <property name="exceptionMappings">  
        <props>  
            <prop key="IOException">error/ioexp</prop>  
            <prop key="java.sql.SQLException">error/sqlexp</prop>  
        </props>  
    </property>  
</bean>

導(dǎo)入其他配置文件

  • 1.通過(guò)<import resource=“文件”/>導(dǎo)入
  • 2.在web.xml中引入
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:文件路徑</param-value>
</context-param>
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener>

最后

感謝你看到這里,看完有什么的不懂的可以在評(píng)論區(qū)問(wèn)我,覺(jué)得文章對(duì)你有幫助的話記得給我點(diǎn)個(gè)贊,每天都會(huì)分享java相關(guān)技術(shù)文章或行業(yè)資訊,歡迎大家關(guān)注和轉(zhuǎn)發(fā)文章!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容