SpringMVC基本使用

SpringMVC是什么?

Spring MVC 是 Spring 框架中的一個模塊,用于構建基于 MVC(Model-View-Controller)設計模式的 Web 應用程序。它分離了應用程序的業務邏輯、用戶界面和用戶輸入,使開發更加模塊化和易于維護。

核心組件

  1. Model:負責封裝應用數據,通常與業務邏輯交互。
  2. View:負責渲染數據,生成用戶界面(如 JSP、Thymeleaf)。
  3. Controller:處理用戶請求,調用業務邏輯并返回視圖。

優點

  • 松耦合:各組件職責明確,易于維護。
  • 靈活性:支持多種視圖技術。
  • 集成性:與 Spring 框架無縫集成,方便使用其他功能(如事務、安全)。

構建基礎環境

先導入依賴

        <!-- 使用 Jakarta Servlet API --><dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.0.0</version><scope>provided</scope></dependency><!-- 使用 Jakarta JSTL API --><dependency><groupId>jakarta.servlet.jsp.jstl</groupId><artifactId>jakarta.servlet.jsp.jstl-api</artifactId><version>3.0.2</version></dependency><!-- JSTL 實現 --><dependency><groupId>org.glassfish.web</groupId><artifactId>jakarta.servlet.jsp.jstl</artifactId><version>3.0.1</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.2.3</version></dependency>

簡單寫一個Servlet

package com.myLearning;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;public class HelloServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getParameter("method");if(method.equals("add")) {req.getSession().setAttribute("msg", "執行add方法");}else{req.getSession().setAttribute("msg","執行了不知所謂的方法");}// 轉發請求req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}
}

創建/WEB-INF/jsp/test.jsp,并寫一個簡單的頁面

<html>
<head><title>測試</title>
</head>
<body>${msg}
</body>
</html>

簡單寫一個主頁hello.jsp

<html>
<head><title>hello</title>
</head>
<body>
<form action="/test" method="post">method:<input type="text" name="method"/><input type="button" value="submit" onclick="submit()">
</form>
</body>
</html>

在web.xml中配置

<?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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><session-config><session-timeout>15</session-timeout></session-config><welcome-file-list><welcome-file>hello.jsp</welcome-file></welcome-file-list><servlet><servlet-name>testServlet</servlet-name><servlet-class>com.myLearning.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>testServlet</servlet-name><url-pattern>/test</url-pattern></servlet-mapping>
</web-app>

最后配置好tomcat,啟動即可訪問

SpringMVC的具體執行流程

用戶請求 -> DispatcherServlet -> HandlerMapping -> HandlerExecutionChain -> HandlerAdapter -> Controller -> ModelAndView -> ViewResolver -> View -> 渲染響應 -> 返回用戶


  1. 用戶發送請求
    用戶通過瀏覽器發起 HTTP 請求,請求被發送到 Spring MVC 的前端控制器 DispatcherServlet

  2. DispatcherServlet 接收請求
    DispatcherServlet 是 Spring MVC 的核心組件,負責接收所有的請求。

  3. HandlerMapping 查找處理器
    DispatcherServlet 調用 HandlerMapping,根據請求的 URL 查找對應的處理器(ControllerHandler)。

    • HandlerMapping 返回一個 HandlerExecutionChain,包含處理器和可能的攔截器。
  4. HandlerAdapter 調用處理器

    • DispatcherServlet 通過 HandlerAdapter 調用處理器(ControllerHandler)。
    • HandlerAdapter 的作用是適配不同類型的處理器(如基于注解的 @Controller、基于接口的 Controller 實現類等)。
    • 常見的 HandlerAdapter 實現包括 RequestMappingHandlerAdapter(用于處理 @Controller@RequestMapping 注解)。
  5. 處理器執行業務邏輯

    • 處理器(Controller)執行業務邏輯,可能會調用 Service 層或 DAO 層。
    • 處理器返回一個 ModelAndView 對象,包含模型數據(Model)和視圖名稱(View)。
  6. 處理攔截器(可選)
    如果配置了攔截器(HandlerInterceptor),在處理器執行前后會調用攔截器的 preHandlepostHandle 方法。

  7. 視圖解析(ViewResolver)
    DispatcherServlet 調用 ViewResolver,根據 ModelAndView 中的視圖名稱解析出具體的視圖對象(如 JSP、Thymeleaf 等)。

  8. 渲染視圖(View)
    DispatcherServlet 將模型數據傳遞給視圖,視圖根據模型數據渲染生成最終的 HTML 內容。

  9. 返回響應
    渲染后的視圖內容通過 DispatcherServlet 返回給客戶端(瀏覽器),完成整個請求-響應流程。

先來簡單寫一個基于SpringMVC的程序

先配置web.xml

<?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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><session-config><session-timeout>15</session-timeout></session-config><welcome-file-list><welcome-file>hello.jsp</welcome-file></welcome-file-list><!--1.注冊DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--關聯一個springmvc的配置文件:【servlet-name】-servlet.xml--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param><!--啟動級別-1--><load-on-startup>1</load-on-startup></servlet><!--/ 匹配所有的請求;(不包括.jsp)--><!--/* 匹配所有的請求;(包括.jsp)--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

編寫一個HelloController.java

package com.myLearning.controller;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;//注意:這里我們先導入Controller接口
public class HelloController implements Controller {public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {//ModelAndView 模型和視圖ModelAndView mv = new ModelAndView();//封裝對象,放在ModelAndView中。Modelmv.addObject("msg","HelloSpringMVC!");//封裝要跳轉的視圖,放在ModelAndView中mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jspreturn mv;}
}

創建一個配置文件springmvc-servlet.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--處理映射器--><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--    處理器適配器--><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/><!--    視圖解析器--><!--視圖解析器:DispatcherServlet給他的ModelAndView--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"><!--前綴--><property name="prefix" value="/WEB-INF/jsp/"/><!--后綴--><property name="suffix" value=".jsp"/></bean><!--Handler--><bean id="/hello" class="com.myLearning.controller.HelloController"/>
</beans>

最后創建/WEB-INF/jsp/hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Hello</title>
</head>
<body>
${msg}
</body>
</html>

然后配置Tomcat,啟動項目,訪問http://localhost:8080/hello ,即可看到結果

現在我們使用注解來完成SpringMVC的開發

由于maven可能會有資源過濾的問題,所以我們需要在pom.xml中添加如下配置

<build><resources><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources>
</build>

我們依舊要配置一個web.xml

<?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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--    <session-config>-->
<!--        <session-timeout>15</session-timeout>-->
<!--    </session-config>--><!--    <welcome-file-list>-->
<!--        <welcome-file>hello.jsp</welcome-file>-->
<!--    </welcome-file-list>--><!--1.注冊DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--關聯一個springmvc的配置文件:【servlet-name】-servlet.xml--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param><!--啟動級別-1--><load-on-startup>1</load-on-startup></servlet><!--/ 匹配所有的請求;(不包括.jsp)--><!--/* 匹配所有的請求;(包括.jsp)--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

然后我們需要編寫SpringMVC的配置文件springmvc-servlet.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 自動掃描包,讓指定包下的注解生效,由IOC容器統一管理 --><context:component-scan base-package="com.myLearning.controller"/><!-- 讓Spring MVC不處理靜態資源 如.mp4 .html等--><mvc:default-servlet-handler /><!--支持mvc注解驅動在spring中一般采用@RequestMapping注解來完成映射關系要想使@RequestMapping注解生效必須向上下文中注冊DefaultAnnotationHandlerMapping和一個AnnotationMethodHandlerAdapter實例這兩個實例分別在類級別和方法級別處理。而annotation-driven配置幫助我們自動完成上述兩個實例的注入。--><mvc:annotation-driven /><!-- 視圖解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前綴 --><property name="prefix" value="/WEB-INF/jsp/" /><!-- 后綴 --><property name="suffix" value=".jsp" /></bean>
</beans>

接著我們需要創建一個controller,來處理請求

在其中我們需要使用@Controller注解來標識這個類是一個controller,并且使用@RequestMapping注解來指定這個controller的訪問路徑

package com.myLearning.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/HelloController")
public class HelloController {//真實訪問地址 : 項目名/HelloController/hello@RequestMapping("/hello")public String sayHello(Model model){//向模型中添加屬性msg與值,可以在JSP頁面中取出并渲染model.addAttribute("msg","hello,SpringMVC");//web-inf/jsp/hello.jspreturn "hello";}
}

確保/WEB-INF/jsp/目錄下有hello.jsp文件,我們上面編寫過

最后我們配置好tomcat服務器,啟動項目,訪問http://localhost:8080/HelloController/hello ,就可以看到我們編寫的頁面了

編寫Controller的兩種方式

經過上面兩種方式的程序編寫,我們現在總結一下Controller的兩種編寫方式:
1.實現Controller接口
2.使用注解@Controller標識,在類中定義處理請求的方法,并使用@RequestMapping等注解來映射請求的URL

實現Controller接口

實現Controller接口,需要重寫handleRequest方法,該方法返回一個ModelAndView對象。

package com.myLearning.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {ModelAndView mv = new ModelAndView();//向模型中添加屬性msg與值,可以在JSP頁面中取出并渲染mv.addObject("msg","hello,SpringMVC");//web-inf/jsp/hello.jspmv.setViewName("hello");return mv;}
}

編寫完后,我們還需要在springmvc.xml中配置我們的Controller

<!--配置Controller-->
<bean name="/hello" class="com.myLearning.controller.HelloController"/>

使用注解@Controller標識

使用@Controller注解標識該類為處理請求的Controller,通過@RequestMapping注解設置請求的路徑。

package com.myLearning.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/HelloController")
public class HelloController {//真實訪問地址 : 項目名/HelloController/hello@RequestMapping("/hello")public String sayHello(Model model){//向模型中添加屬性msg與值,可以在JSP頁面中取出并渲染model.addAttribute("msg","hello,SpringMVC");//web-inf/jsp/hello.jspreturn "hello";}
}

然后,我們需要在springmvc.xml中配置掃描包即可

<!--掃描包-->
<context:component-scan base-package="com.myLearning.controller"/>

Restful風格

Restful就是一個資源定位及資源操作的風格。不是標準也不是協議,只是一種風格。基于這個風格設計的軟件可以更簡潔,更有層次,更易于實現緩存等機制。

功能

資源:互聯網所有的事物都可以抽象為資源
資源操作:使用POST、DELETE、PUT、GET,使用不同方法對資源進行操作。
分別對應 添加、刪除、修改、查詢。

傳統方式操作資源

通過不同的參數來實現不同的效果!方法單一,都是get。
http://127.0.0.1/item/queryItem.action?id=1 查詢,GET
http://127.0.0.1/item/saveItem.action 新增,POST

使用RESTful操作資源

http://127.0.0.1/item/1 查詢,GET
http://127.0.0.1/item 新增,POST

使用Restful風格優化代碼

那么我們如何獲取restful風格中傳遞的參數呢?請看下面的示例:
我們先編寫一個/Web-INF/jsp/test1.jsp頁面用于測試:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>test1</title>
</head>
<body>
計算結果為:${rst}
${msg}
</body>
</html>

然后我們創建一個新的controller類,在這個類中,我們指明訪問路徑,以及路徑中的參數名用于獲取從路徑中傳遞的參數:

package com.myLearning.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class Controller2 {
//    在定義時,我們可以指定對應位置映射的參數名@RequestMapping("/t1/{a}/{b}")
//    我們可以在參數中指明我們將要從路徑的哪個參數名中獲取對應參數public String test1(@PathVariable("a") int a, @PathVariable("b") int b, Model model) {model.addAttribute("rst",a + b);model.addAttribute("msg", "Hello World");return "test1";}
}

除了我們可以指定參數之外,我們還可以設置方法對應的請求類型,比如我們只希望這個方法處理get請求,那么我們可以這樣寫:

@RequestMapping(value = "/t1/{a}/{b}", method = RequestMethod.GET)

同理,可以設置method為POST,PUT,DELETE等,用于處理不同類型的請求。

還有另一種形式可以指定請求的類型:

@GetMapping("/t1/{a}/{b}")

這種形式是用于指定處理Get類型請求的的簡寫形式,類似的表達還有@PostMapping, @PutMapping, @DeleteMapping

SpringMVC中的結果跳轉

一般方式

在一般情況下,我們讓SpringMVC通過我們返回的視圖名稱,以及經過視圖解析器處理后,得到我們最后要跳轉的頁,如:
在SpringMVC配置文件中設置視圖解析器:

    <!-- 視圖解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前綴 --><property name="prefix" value="/WEB-INF/jsp/" /><!-- 后綴 --><property name="suffix" value=".jsp" /></bean>

然后我們就可以在方法中返回視圖名稱,交由視圖解析器處理,如:

@RequestMapping("/t1/{a}/{b}")
public String test1(@PathVariable("a") int a, @PathVariable("b") int b, Model model) {model.addAttribute("rst",a + b);model.addAttribute("msg", "Hello World");return "test1";
}

使用Servlet API方式

我們也可以在方法中獲取Servlet 中使用的變量,并使用其API
完成轉發

    @GetMapping("/t1/{a}/{b}")public void test1(@PathVariable("a") int a, @PathVariable("b") int b, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, ServletException, IOException {request.setAttribute("rst",a + b);request.setAttribute("msg", "Hello World!!!");// 使用Servlet API進行轉發request.getRequestDispatcher("/WEB-INF/jsp/test1.jsp").forward(request, response);}

完成重定向

    @GetMapping("/t1/{a}/{b}")public void test1(@PathVariable("a") int a, @PathVariable("b") int b, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, ServletException, IOException {request.setAttribute("rst",a + b);request.setAttribute("msg", "Hello World!!!");// 使用Servlet API進行重定向response.sendRedirect(request.getContextPath() + "/hello.jsp");}

在沒有視圖解析器的情況下,我們也可以通過返回字符串的方式完成轉發和重定向

完成轉發

    @GetMapping("/t1/{a}/{b}")public String test2(@PathVariable("a") int a, @PathVariable("b") int b,Model model)  {// 無視圖解析器完成轉發return "forward:/hello.jsp";}

完成重定向

    @GetMapping("/t1/{a}/{b}")public String test2(@PathVariable("a") int a, @PathVariable("b") int b,Model model)  {// 無視圖解析器完成重定向return "redirect:/hello.jsp";}

在有視圖解析器的情況下,完成重定向和轉發

完成重定向

    @GetMapping("/t1/{a}/{b}")public String test2(@PathVariable("a") int a, @PathVariable("b") int b,Model model)  {// 有視圖解析器完成重定向return "redirect:/hello.jsp";}

完成轉發

    @GetMapping("/t1/{a}/{b}")public String test2(@PathVariable("a") int a, @PathVariable("b") int b,Model model)  {// 有視圖解析器完成轉發return "hello";}

SpringMVC處理提交數據

我們通常會在請求中附帶額外的參數數據,如:http://localhost:8080/hello?name=張三&age=18,除此之外還會有類似username,password等數據,我們如何獲取這些數據呢?

當我們要接收一個非對象數據時

我們可以使用@RequestParam注解來獲取傳遞的參數
假設我們有一個請求,請求地址為:http://localhost:8080/test1?name=jack
我們可以通過如下方式獲取到name的值:

    @RequestMapping("/test1")public String test3(@RequestParam("name") String name, Model model) {System.out.println(name);return "hello";}

當我們接收一個實體類對象時

我們可以直接將實體類對象作為方法參數,SpringMVC會自動將請求中的參數封裝到實體類對象中
假設我們有一個實體類User,如下:

package com.myLearning.pojo;import org.apache.ibatis.type.Alias;import java.io.Serializable;@Alias("user")
public class User implements Serializable {private int id;private String name;private String pwd;public User() {}public User(int id, String name, String pwd) {this.id = id;this.name = name;this.pwd = pwd;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", pwd='" + pwd + '\'' +'}';}
}

并且假設我們的url為:http://localhost:8080/test1?name=jack&pwd=123456&id=1
我們可以通過以下方式獲取參數:

    @RequestMapping("/test1")public String test3(User user, Model model) {System.out.println(user);return "hello";}

Model與ModelMap

這二者都是用于向前端視圖頁面傳遞數據的,ModelMap繼承了LinkedHashMap,具有LinkedHashMap的所有方法,而Model是精簡版,我們大部分時間使用Model即可。

亂碼問題

如果前端傳遞的數據中包括中文,如: 張三、李四、利姆露等,那么我們在處理的時候可能會出現亂碼問題,這個時候,我們可以通過以下方式解決:

使用Spring提供的編碼過濾器

在web.xml中添加以下代碼:

<filter><filter-name>encoding</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>encoding</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

還可以修改tomcat的配置文件

在tomcat的conf/server.xml中設置以下代碼:

<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" URIEncoding="UTF-8"/>

JSON

什么是JSON?

JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,易于人閱讀和編寫,同時也易于機器解析和生成。它基于JavaScript的一個子集,但獨立于編程語言,廣泛用于Web應用中的數據交換。其本質其實就是一個字符串,只不過這個字符串的格式比較特殊,符合一定的規則。

JSON的特點:

  • 輕量級:JSON格式簡潔,數據量小,適合網絡傳輸。

  • 易讀性:結構清晰,便于人類閱讀和理解。

  • 獨立性:不依賴特定語言,幾乎所有編程語言都支持JSON。

  • 數據結構:支持對象(鍵值對)和數組(有序列表)兩種主要結構。

JSON和Javascript對象的轉換

JSON和JavaScript對象之間的轉換是JSON數據在Web應用中常用的操作。在JavaScript中,可以使用內置的JSON對象來進行轉換。

JSON字符串轉換為JavaScript對象

使用JSON.parse()方法可以將JSON字符串轉換為JavaScript對象。

var jsonString = '{"name":"John", "age":30, "city":"New York"}';
var jsonObject = JSON.parse(jsonString);
console.log(jsonObject.name); // 輸出 "John"

JavaScript對象轉換為JSON字符串

使用JSON.stringify()方法可以將JavaScript對象轉換為JSON字符串。

javascript
var jsonObject = {name: "John", age: 30, city: "New York"};
var jsonString = JSON.stringify(jsonObject);
console.log(jsonString); // 輸出 '{"name":"John","age":30,"city":"New York"}'

使用Controller返回JSON數據

使用Jackson完成JSON轉換

首先我們需要添加Jackson的依賴:

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.18.3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.18.3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.18.3</version></dependency>

然后我們編寫一個controller類,用于返回JSON數據:

package com.myLearning.controller;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.myLearning.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class Controller1 {@RequestMapping("/json1")@ResponseBody//@ResponseBody注解,指定返回的結果不走視圖解析器,而是直接作字符串返回public String json1() throws JsonProcessingException {//創建一個jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user = new User(1,"利姆露","666666");//將我們的對象解析成為json格式String str = mapper.writeValueAsString(user);//由于@ResponseBody注解,這里會將str轉成json格式返回;十分方便return str;}
}
解決亂碼問題

測試時,我們會發現顯示有亂碼問題,此時我們可以通過設置@RequestMaping的produces屬性來實現:

package com.myLearning.controller;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.myLearning.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class Controller1 {
//    我們設置了其produces的屬性@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")@ResponseBody//@ResponseBody注解,指定返回的結果不走視圖解析器,而是直接作字符串返回public String json1() throws JsonProcessingException {//創建一個jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user = new User(1,"利姆露","666666");//將我們的對象解析成為json格式String str = mapper.writeValueAsString(user);//由于@ResponseBody注解,這里會將str轉成json格式返回;十分方便return str;}
}

除此之外,我們還可以在springmvc.xml中配置消息轉換器,也可以解決亂碼問題:

<!--配置消息轉換器-->
<mvc:annotation-driven><mvc:message-converters register-defaults="true"><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="UTF-8"/></bean><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="objectMapper"><bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"><property name="failOnEmptyBeans" value="false"/></bean></property></bean></mvc:message-converters>
</mvc:annotation-driven>

現在我們已經可以成功解決亂碼問題了,但是現在我們每設置一個方法返回JSON字符串,我們都需要添加@ResponseBody注解,這樣顯然是不方便的,所以我們可以直接在類的上方添加@RestController注解,這樣就可以省略掉每個方法的@ResponseBody注解了。

package com.myLearning.controller;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.myLearning.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class Controller1 {
//    我們設置了其produces的屬性@RequestMapping(value = "/json1")public String json1() throws JsonProcessingException {//創建一個jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user = new User(1,"利姆露","666666");//將我們的對象解析成為json格式String str = mapper.writeValueAsString(user);//由于@ResponseBody注解,這里會將str轉成json格式返回;十分方便return str;}
}
輸出時間格式

如果我們直接使用ObjectMapper來輸出時間的話,輸出的格式默認為時間戳,即1970年到現在的毫秒數,這可能不是我們想要的,所以我們需要自定義時間格式。

    @RequestMapping("/json2")public String json2() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();//不使用時間戳的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定義日期格式對象SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//指定日期格式mapper.setDateFormat(sdf);Date date = new Date();String str = mapper.writeValueAsString(date);return str;}
封裝成工具類

我們可以發現,每次使用ObjectMapper時都需要進行一些重復的操作,所以我們可以將其封裝成一個工具類,方便我們使用。

package com.myLearning.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
public class JsonUtils {public static String getJson(Object object) {return getJson(object,"yyyy-MM-dd HH:mm:ss");}public static String getJson(Object object,String dateFormat) {ObjectMapper mapper = new ObjectMapper();//不使用時間差的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定義日期格式對象SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);//指定日期格式mapper.setDateFormat(sdf);try {return mapper.writeValueAsString(object);} catch (JsonProcessingException e) {e.printStackTrace();}return null;}
}

使用fastjson完成json轉換

FastJSON 是阿里巴巴開源的一個高性能的 JSON 庫,用于 Java 對象與 JSON 數據之間的序列化(將 Java 對象轉換為 JSON 字符串)和反序列化(將 JSON 字符串轉換為 Java 對象)。它是目前 Java 生態中性能最好的 JSON 庫之一,廣泛應用于各種 Java 項目中。

為了使用fastjson,需要在pom.xml文件中添加以下依賴:

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.56</version></dependency>

簡單使用:

    @RequestMapping("/json3")public String json3() throws JsonProcessingException {// 創建一個 User 對象User user = new User(1, "利姆露", "123456233333333333");// 序列化:將 User 對象轉換為 JSON 字符串String jsonString = JSON.toJSONString(user);System.out.println("序列化結果:" + jsonString);// 反序列化:將 JSON 字符串轉換為 User 對象User parsedUser = JSON.parseObject(jsonString, User.class);System.out.println("反序列化結果:" + parsedUser);return jsonString;}

整合SSM框架

先創建底層數據庫

create database `ssmbuild`;use `ssmbuild`;create table `books`(`bookID` int(10) not null auto_increment comment 'id',`bookName` varchar(100) not null comment '書名',`bookCounts` int(10) not null comment '數量',`detail` varchar(255) not null comment '描述',key `bookID` (`bookID`) 
)ENGINE=InnoDB default charset=utf8;insert into `books` (`bookID`,`bookName`,`bookCounts`,`detail`) VALUES
(1,'紅樓夢',20,'理想的破滅'),
(2,'水滸傳',30,'現實主義悲劇'),
(3,'c primer plus',40,'c 語言基礎入門教程');

導入相關依賴

    <dependencies><!-- MyBatis 核心依賴 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version> <!-- 請使用最新版本 --></dependency><!-- 數據庫驅動(例如 MySQL) --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version> <!-- 請根據數據庫版本選擇 --></dependency><!-- JUnit 5 核心依賴 --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.10.0</version> <!-- 請使用最新版本 --><scope>test</scope></dependency><!-- JUnit 5 測試引擎 --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.10.0</version><scope>test</scope></dependency><!-- Log4j2 核心依賴 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.20.0</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.20.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.2.3</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>6.2.3</version></dependency><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.4</version></dependency><!-- 使用 Jakarta Servlet API --><dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.0.0</version><scope>provided</scope></dependency><!-- 使用 Jakarta JSTL API --><dependency><groupId>jakarta.servlet.jsp.jstl</groupId><artifactId>jakarta.servlet.jsp.jstl-api</artifactId><version>3.0.2</version></dependency><!-- JSTL 實現 --><dependency><groupId>org.glassfish.web</groupId><artifactId>jakarta.servlet.jsp.jstl</artifactId><version>3.0.1</version></dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.18.3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.18.3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.18.3</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.56</version></dependency> <dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.4</version></dependency></dependencies>

防止資源導出問題

在pom.xml中配置resources,防止資源導出時的問題


<!--    在build中配置resources,防止資源導出時的問題--><build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource></resources></build>

創建需要的軟件包和資源文件

需要的軟件包有:controller、service、dao、pojo

需要創建的資源配置文件:
mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="com.myLearning.pojo"/></typeAliases></configuration>

applicationContext.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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"></beans>

database.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456

創建實體類

package com.myLearning.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {private int bookID;private String bookName;private int bookCounts;private String detail;
}

創建dao接口

package com.myLearning.dao;import com.myLearning.pojo.Book;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface BookMapper {// 添加一本書int addBook(Book book);// 刪除一本書int deleteBook(Book book);// 修改一本書int updateBook(Book book);// 查詢所有書List<Book> getAllBooks();// 查詢包含關鍵字的書List<Book> getBookByStr(@Param("str") String str);
}

創建BookMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--用于綁定剛剛創建的Dao(Mapper)接口-->
<mapper namespace="com.myLearning.dao.BookMapper"><insert id="addBook" parameterType="book">insert into books(`bookName`,`bookCounts`,`detail`) values(#{bookName},#{bookCounts},#{detail});
</insert><delete id="deleteBook" parameterType="book">deletefrom bookswhere `bookID` = #{bookID};
</delete><update id="updateBook" parameterType="book">update booksset `bookName` = #{bookName},`bookCounts` = #{bookCounts},`detail` = #{detail}where `bookID` = #{bookID};
</update><select id="getAllBooks" resultType="book">select * from books;</select><select id="getBookByStr" parameterType="String" resultType="book">select * from books where`bookName` like concat('%',#{str},'%')</select></mapper>

在mybatis-config.xml中配置mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><!-- 標準日志工廠實現 --><setting name="logImpl" value="STDOUT_LOGGING"/></settings><typeAliases><package name="com.myLearning.pojo"/></typeAliases><mappers><mapper class="com.myLearning.dao.BookMapper"/></mappers>
</configuration>

創建service接口

package com.myLearning.service;import com.myLearning.pojo.Book;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface BookService {// 添加一本書int addBook(Book book);// 刪除一本書int deleteBook(Book book);// 修改一本書int updateBook(Book book);// 查詢所有書List<Book> getAllBooks();// 查詢包含關鍵字的書List<Book> getBookByStr( String str);
}

創建service實現類(本質就是在調用dao層的接口)

package com.myLearning.service;import com.myLearning.dao.BookMapper;
import com.myLearning.pojo.Book;import java.util.List;public class BookServiceImpl implements BookService {private BookMapper bookMapper;public BookMapper getBookMapper() {return bookMapper;}public void setBookMapper(BookMapper bookMapper) {this.bookMapper = bookMapper;}@Overridepublic int addBook(Book book) {return bookMapper.addBook(book);}@Overridepublic int deleteBook(Book book) {return bookMapper.deleteBook(book);}@Overridepublic int updateBook(Book book) {return bookMapper.updateBook(book);}@Overridepublic List<Book> getAllBooks() {return bookMapper.getAllBooks();}@Overridepublic List<Book> getBookByStr(String str) {return bookMapper.getBookByStr(str);}
}

創建spring-dao.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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--關聯數據庫配置文件--><context:property-placeholder location="classpath:database.properties"/><!--    連接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="maxPoolSize" value="30"/><property name="minPoolSize" value="10"/>
<!--    關閉連接后不自動commit--><property name="autoCommitOnClose" value="false"/>
<!--    獲取連接超時時間--><property name="checkoutTimeout" value="10000"/>
<!--    獲取連接失敗重試次數--><property name="acquireRetryAttempts" value="2"/>
</bean><!--    sqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/>
<!--        綁定mybatis的配置文件--><property name="configLocation" value="classpath:mybatis-config.xml"/></bean><!--    配置dao接口掃描包,動態實現Dao接口注入到Spring中--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--        要掃描的dao包--><property name="basePackage" value="com.myLearning.dao"/></bean>
</beans>

創建spring-service.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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 指定掃描的包,這個包下的注解會生效   --><!--    掃描service下的包--><context:component-scan base-package="com.myLearning.service"/><context:annotation-config/><!--    將業務類注入到Spring中--><bean id="bookServiceImpl" class="com.myLearning.service.BookServiceImpl"><property name="bookMapper" ref="bookMapper"/></bean><!--    配置聲明式事務--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><constructor-arg ref="dataSource" /></bean><!--    配置事務通知--><tx:advice id="txAdvice" transaction-manager="transactionManager"><!--        給哪些方法配置事務--><tx:attributes><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice><!--    aop配置事務切入--><aop:config><!--        設置切入點,給com.myLearning.mapper包內所有類中的所有方法配置事務--><aop:pointcut id="txPointCut" expression="execution(* com.myLearning.service.*.*(..))"/><!--    設置通知--><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/></aop:config>
</beans>

同時需要在項目結構中創建一個spring的子模塊,并在其中添加我們已經創建的三個spring配置文件,applicationContext.xml、spring-mvc.xml、spring-service.xml

創建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"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--    注解驅動--><mvc:annotation-driven/>
<!--   靜態資源過濾--><mvc:default-servlet-handler/>
<!--    掃描寶:controller-->
<context:component-scan base-package="com.myLearning.controller"/><!--    視圖解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean></beans>

在applicationContext.xml中導入這個配置文件

    <import resource="classpath:spring-mvc.xml"/>

在項目模塊中添加web子模塊,并配置web.xml

<?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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--    DispatchServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</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>
</filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><session-config><session-timeout>15</session-timeout></session-config>
</web-app>

同時在/WEB-INF中創建jsp文件夾

創建BookController.java

現在我們已經完成了ssm的框架整合,接著我們可以為我們的網站添加功能了,首先我們需要創建一個BookController.java

package com.myLearning.controller;import com.myLearning.pojo.Book;
import com.myLearning.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;@Controller
@RequestMapping("/book")
public class BookController {@Autowired@Qualifier("bookServiceImpl")private BookService bookService;@RequestMapping("/getAllBooks")public String getAllBooks(Model model) {List<Book> books = bookService.getAllBooks();model.addAttribute("books", books);return "getAllBooks";}
}

創建index.jsp以及/WEB-INF/jsp/getAllBooks.jsp

<!--index.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>主頁</title><style>a{text-decoration: none;color: cornflowerblue;font-size: 20px;}h3{width: 180px;height: 60px;margin: 100px auto;text-align: center;line-height: 60px;background: ghostwhite;}</style>
</head>
<body>
<h3><a href="${pageContext.request.contextPath}/book/getAllBooks">點擊進入書籍頁面</a>
</h3>
</body>
</html>
<!--/WEB-INF/jsp/getAllBooks.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>書籍展示頁面</title><%--   使用cdn引入  BootStrap 用于美化界面--%><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>書籍列表</small></h1></div></div></div>
</div><div class="row clearfix"><div class="col-md-12 column"><table class="table table-hover table-striped"><thead><tr><th>書籍編號</th><th>書籍名稱</th><th>書籍數量</th><th>書籍詳情</th></tr></thead><tbody><c:forEach var="book" items="${books}"><tr><td>${book.bookID}</td><td>${book.bookName}</td><td>${book.bookCounts}</td><td>${book.detail}</td></tr></c:forEach></tbody></table></div>
</div></body>
</html>

接著我們可以進一步添加功能,如添加書籍,刪除書籍,修改書籍信息

首先我們修改書籍展示的頁面getAllBooks.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>書籍展示頁面</title><%--   使用cdn引入  BootStrap 用于美化界面--%><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>書籍列表</small></h1></div></div><div class="row"><div class="col-md-4 column"><a class="btn btn-primary" href="/book/toAddBook">新增書籍</a></div><div class="col-md-8 column"><form class="d-flex justify-content-end" action="${pageContext.request.contextPath}/book/queryBook" method="post"><!-- 錯誤信息 --><span class="text-danger fw-bold me-2">${error}</span><!-- 輸入框 --><input type="text" name="queryName" class="form-control me-2" placeholder="請輸入要查詢的書籍名稱" /><!-- 查詢按鈕 --><input type="submit" class="btn btn-primary" value="查詢"></form></div></div></div><div class="row clearfix"><div class="col-md-12 column"><table class="table table-hover table-striped"><thead><tr><th>書籍編號</th><th>書籍名稱</th><th>書籍數量</th><th>書籍詳情</th><th>操作</th></tr></thead><tbody><c:forEach var="book" items="${books}"><tr><td>${book.bookID}</td><td>${book.bookName}</td><td>${book.bookCounts}</td><td>${book.detail}</td><td><a href="${pageContext.request.contextPath}/book/toUpdate?bookID=${book.bookID}&bookName=${book.bookName}&bookCounts=${book.bookCounts}&detail=${book.detail}">修改</a>&nbsp; | &nbsp;<a href="${pageContext.request.contextPath}/book/deleteBook?bookID=${book.bookID}&bookName=${book.bookName}&bookCounts=${book.bookCounts}&detail=${book.detail}">刪除</a></td></tr></c:forEach></tbody></table></div>
</div>
</div>
</body>
</html>

然后我們在jsp文件夾中創建一個addBook.jsp頁面,用于添加書籍信息:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>添加書籍</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>新增書籍</small></h1></div></div></div><form action="${pageContext.request.contextPath}/book/addBook" method="post"><div class="mb-3"><label  class="form-label">添加的書名</label><input  type="text" name="bookName" class="form-control" required/></div><div class="mb-3"><label  class="form-label">添加的數量</label><input  type="text" name="bookCounts" class="form-control" required/></div><div class="mb-3"><label  class="form-label">書籍相關詳情</label><input  type="text" name="detail" class="form-control" required/></div><button type="submit" class="btn btn-primary">添加</button></form></div>
</body>
</html>

然后我們繼續在jsp文件夾下創建一個updateBook.jsp,用于更新書籍信息:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>添加書籍</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>修改書籍</small></h1></div></div></div><form action="${pageContext.request.contextPath}/book/updateBook" method="post"><input type="hidden" name="bookID" value="${qBook.bookID}"><div class="mb-3"><label  class="form-label">修改書名</label><input  type="text" name="bookName" class="form-control" value="${qBook.bookName}" required/></div><div class="mb-3"><label  class="form-label">修改數量</label><input  type="text" name="bookCounts" class="form-control" value="${qBook.bookCounts}" required/></div><div class="mb-3"><label  class="form-label">修改書籍相關詳情</label><input  type="text" name="detail" class="form-control" value="${qBook.detail}" required/></div><button type="submit" class="btn btn-primary">修改</button></form></div>
</body>
</html>

然后修改BookController.java文件

package com.myLearning.controller;import com.myLearning.pojo.Book;
import com.myLearning.service.BookService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.List;@Controller
@RequestMapping("/book")
public class BookController {@Autowired@Qualifier("bookServiceImpl")private BookService bookService;@RequestMapping("/getAllBooks")public String getAllBooks(Model model) {List<Book> books = bookService.getAllBooks();model.addAttribute("books", books);return "getAllBooks";}@RequestMapping("/toAddBook")public String toAddBook(Model model) {return "addBook";}@RequestMapping("/addBook")public String addBook(Book book, Model model) {bookService.addBook(book);return "redirect:/book/getAllBooks";}@RequestMapping("/toUpdate")public String toUpdate(Book book, Model model) {model.addAttribute("qBook", book);return "updateBook";}@RequestMapping("/updateBook")public String updateBook(Book book, Model model) {bookService.updateBook(book);return "redirect:/book/getAllBooks";}@RequestMapping("/deleteBook")public String deleteBook(Book book, Model model) {bookService.deleteBook(book);return "redirect:/book/getAllBooks";}@RequestMapping("/queryBook")public String queryBook(@RequestParam("queryName") String str, Model model) {List<Book> books = bookService.getBookByStr(str);if(books.isEmpty()) model.addAttribute("error", "未找到呢,親");model.addAttribute("books", books);return "getAllBooks";}
}

Ajax基本使用

什么是Ajax?

Ajax = Asynchronous JavaScript and XML(異步JavaScript和XML)。

Ajax是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。

通過在后臺與服務器進行少量數據交換,Ajax可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。

傳統的網頁(不使用Ajax)如果需要更新內容,必須重載整個網頁頁面。

Ajax的原理

Ajax的工作原理相當于在用戶和服務器之間加了一個中間層(Ajax引擎),使用戶操作與服務器響應異步化。這樣把以前的一些服務器負擔的工作轉嫁到客戶端,利于客戶端閑置的處理能力來處理,減輕服務器和帶寬的負擔,從而達到節約ISP的空間和帶寬租用成本的目的。

Ajax使用XMLHttpRequest對象和服務器通信,這種方式的通信在客戶端和服務器之間建立了一條雙向的通信渠道,服務器不再是被動的響應,而是主動向客戶端推送信息。

Ajax的簡單使用

jQuery為我們封裝了Ajax的一些使用,讓我們能夠更加方便地完成ajax。

導入jQuery

為此,我們先要導入jQuery的jar包。
我們需要訪問jQuery官網,https://jquery.com/download/
然后下載Download the uncompressed development version of jQuery 3.7.1
并將下載的文件jquery-3.7.1.js 放在我們項目中,假設我們放在了/WEB-INF/statics/js目錄下

編寫一個index.jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %><html>
<head><!-- 導入jQuery的庫 --><script src="${pageContext.request.contextPath}/statics/js/jquery-3.7.1.js"></script><script>function uT(){$.post({url: "${pageContext.request.contextPath}/mySolve",data: {"username":$("#username").val()},success:function (res){$("#usernamestate").text(res);if(res==="ok"){$("#usernamestate").css("color","green")}else{$("#usernamestate").css("color","red")}}})}function pT(){$.post({url: "${pageContext.request.contextPath}/mySolve",data: {"password":$("#password").val()},success:function (res){$("#passwordstate").text(res);if(res==="ok"){$("#passwordstate").css("color","green")}else{$("#passwordstate").css("color","red")}}})}</script><title>ajax異步用戶登錄</title>
</head>
<body><form action="" method="post"><p>用戶名:<input type="text" name="username" id="username" onblur="uT()"/> <span id="usernamestate"></span></p><p>密碼:    <input type="password" name="password" id="password" onblur="pT()"/>  <span id="passwordstate"></span></p><input type="submit" />
</form></body>
</html>

解析:
在這個頁面中,我們讓用戶輸入它的用戶名以及密碼,并且在輸入框失去焦點時,調用我們在javascript中的函數uT()和pT(),這兩個函數分別向服務器發送請求,獲取服務器返回的數據,然后根據返回的數據來改變span標簽中的內容以及顏色。
在uT()以及pt()中,我們使用jQuery的post()方法向服務器發送請求,其中,url是請求的地址,data是發送的數據,success是請求成功后執行的函數,res是服務器返回的數據。在success函數中,我們根據res的值來改變span標簽中的內容以及顏色。

然后我們編寫一個Controller來處理這個請求:

package com.myLearning.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class testController {@RequestMapping("/mySolve")public String myResolve( @RequestParam(value = "username" ,required = false) String username,@RequestParam(value = "password" ,required = false)  String password) {if(username != null){if(username.equals("admin")){return "ok";}else{return "用戶名不存在";}}if(password != null){if(password.equals("123456")){return "ok";}else{return "密碼不正確";}}return "error";}
}

解決亂碼問題

我們此時如果直接運行我們的代碼,可能會出現亂碼的問題,為此我們需要在我們的sprintmvc的配置文件,假設是applicationContext.xml中添加如下配置:

    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.StringHttpMessageConverter"><property name="defaultCharset" value="UTF-8"/></bean><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="defaultCharset" value="UTF-8"/></bean></list></property></bean>

這樣就可以解決亂碼的問題了

攔截器interceptor

攔截器是SpringMVC中的一種機制,它可以在請求到達目標方法之前進行一些處理,也可以在目標方法執行之后進行一些處理,它的作用類似于過濾器,但是它只能攔截請求,不能攔截靜態資源,它的使用步驟如下:

  1. 創建一個類,實現HandlerInterceptor接口,重寫preHandle、postHandle、afterCompletion方法,其中preHandle方法在目標方法執行之前執行,postHandle方法在目標方法執行之后執行,afterCompletion方法在請求完成之后執行
package com.myLearning.interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class MyInterceptor implements HandlerInterceptor {@Override
//    返回true表示這個攔截器放行,返回false表示攔截這個請求public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("方法執行前,攔截器進行攔截檢測");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("方法執行后");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("請求完成");}
}
  1. 在springmvc.xml中配置攔截器
    <mvc:interceptors><mvc:interceptor>
<!--            配置攔截器攔截的路徑,/**表示所有路徑--><mvc:mapping path="/**"/>
<!--            配置我們的攔截器--><bean class="com.myLearning.interceptor.MyInterceptor"/></mvc:interceptor></mvc:interceptors>

文件上傳和下載

文件上傳

前端表單配置

為了實現文件上傳,首先我們需要再我們的前端表單中配置enctype的屬性
這個屬性的默認值為application/x-www-form-urlencoded,這種情況下會將我們的值處理為url編碼,而如果我們要上傳文件,那么這個屬性應該設置為multipart/form-data,表示將我們的表單數據以二進制的形式進行處理

<form action="/upload" enctype="multipart/form-data" method="post"><input type="file" name="file"/><input type="submit" value="upload">
</form>

在springmvc配置文件中配置bean

 <!--文件上傳配置--><bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>

在 web.xml 中配置 Multipart 支持

    <!--    DispatchServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></init-param><load-on-startup>1</load-on-startup><multipart-config><max-file-size>10485760</max-file-size> <!-- 10MB --><max-request-size>10485760</max-request-size> <!-- 10MB --><file-size-threshold>1048576</file-size-threshold> <!-- 1MB --></multipart-config></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>

controller

package com.myLearning.controller;import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import java.io.*;@Controller
public class FileController {//@RequestParam("file") 將name=file控件得到的文件封裝成CommonsMultipartFile 對象//批量上傳CommonsMultipartFile則為數組即可@RequestMapping("/upload")public String fileUpload(@RequestParam("file") MultipartFile file , HttpServletRequest request) throws IOException, IOException {//獲取文件名 : file.getOriginalFilename();String uploadFileName = file.getOriginalFilename();//如果文件名為空,直接回到首頁!if ("".equals(uploadFileName)){return "redirect:/index.jsp";}System.out.println("上傳文件名 : "+uploadFileName);//上傳路徑保存設置String path = request.getServletContext().getRealPath("/upload");//如果路徑不存在,創建一個File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}System.out.println("上傳文件保存地址:"+realPath);InputStream is = file.getInputStream(); //文件輸入流OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件輸出流//讀取寫出int len=0;byte[] buffer = new byte[1024];while ((len=is.read(buffer))!=-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return "redirect:/index.jsp";}
}

第二種controller寫法

    /** 采用file.Transto 來保存上傳的文件*/@RequestMapping("/upload2")public String  fileUpload2(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {//上傳路徑保存設置String path = request.getServletContext().getRealPath("/upload");File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}//上傳文件地址System.out.println("上傳文件保存地址:"+realPath);//通過CommonsMultipartFile的方法直接寫文件(注意這個時候)file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));return "redirect:/index.jsp";}

文件下載

controller

    @RequestMapping(value="/download")public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{//要下載的圖片地址String  path = request.getServletContext().getRealPath("/upload");String  fileName = "vertin.jpg";//1、設置response 響應頭response.reset(); //設置頁面不緩存,清空bufferresponse.setCharacterEncoding("UTF-8"); //字符編碼response.setContentType("multipart/form-data"); //二進制傳輸數據//設置響應頭response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));File file = new File(path,fileName);//2、 讀取文件--輸入流InputStream input=new FileInputStream(file);//3、 寫出文件--輸出流OutputStream out = response.getOutputStream();byte[] buff =new byte[1024];int index=0;//4、執行 寫出操作while((index= input.read(buff))!= -1){out.write(buff, 0, index);out.flush();}out.close();input.close();return null;}

前端

<a href="/download">點擊下載</a>

筆記總結于此地址

https://www.bilibili.com/video/BV1aE41167Tu?vd_source=16bf0c507e4a78c3ca31a05dff1bee4e&spm_id_from=333.788.videopod.episodes

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

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

相關文章

Qt之MVC架構MVD

什么是MVC架構&#xff1a; MVC模式&#xff08;Model–view–controller&#xff09;是軟件工程中的一種軟件架構模式&#xff0c;把軟件系統分為三個基本部分&#xff1a;模型&#xff08;Model&#xff09;、視圖&#xff08;View&#xff09;和控制器&#xff08;Controll…

Stream 流中 flatMap 方法詳解

&#x1f3af; 1. flatMap() 到底是啥&#xff1f; flatMap() 是 Stream 里的中間操作&#xff0c;它的作用可以分兩步理解&#xff1a; 第一步&#xff1a;對流里的每個元素&#xff0c;先**映射&#xff08;轉換&#xff09;**成一個 Stream。第二步&#xff1a;把多個子流…

(C語言)理解 回調函數 和 qsort函數

一. 回調函數 1. 什么是回調函數&#xff1f; 回調函數&#xff08;Callback Function&#xff09;是通過 函數指針 調用的函數。其本質是&#xff1a; 將函數作為參數傳遞給另一個函數&#xff0c;并在特定條件下被調用&#xff0c;實現 反向控制。 2. 回調函數的使用 回調函…

vscode記錄

vs code 下載安裝&#xff0c;git 配置&#xff0c;插件安裝_vscode安裝git插件-CSDN博客 手把手教你在VS Code中使用 Git_vscode如何輸入git命令-CSDN博客 VS Code | 如何快速重啟VS Code&#xff1f;_vscode 怎么一鍵全部重啟-CSDN博客 1&#xff0c;安裝插件與git集成 2&am…

唯品會商品詳情頁架構設計與實現:高并發場景下的技術實踐?

引言 唯品會作為國內領先的電商平臺&#xff0c;其商品詳情頁需要應對海量用戶的高并發訪問&#xff0c;同時保證低延遲和高可用性。本文將從架構設計、數據庫優化、緩存策略、前端渲染等方面&#xff0c;結合代碼示例&#xff0c;深入解析唯品會商品詳情頁的技術實現。 一、…

大數據學習(80)-數倉分層

&#x1f34b;&#x1f34b;大數據學習&#x1f34b;&#x1f34b; &#x1f525;系列專欄&#xff1a; &#x1f451;哲學語錄: 用力所能及&#xff0c;改變世界。 &#x1f496;如果覺得博主的文章還不錯的話&#xff0c;請點贊&#x1f44d;收藏??留言&#x1f4dd;支持一…

數智讀書筆記系列021《大數據醫療》:探索醫療行業的智能變革

一、書籍介紹 《大數據醫療》由徐曼、沈江、余海燕合著&#xff0c;由機械工業出版社出版 。徐曼是南開大學商學院副教授&#xff0c;在大數據驅動的智能決策研究領域頗有建樹&#xff0c;尤其在大數據驅動的醫療與健康決策方面有著深入研究&#xff0c;曾獲天津優秀博士論文、…

SpringSecurity——前后端分離登錄認證

SpringSecurity——前后端分離登錄認證的整個過程 前端&#xff1a; 使用Axios向后端發送請求 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>登錄</title><script src"https://cdn…

qt下載和安裝教程國內源下載地址

qt不斷在更新中&#xff0c;目前qt6日漸成熟&#xff0c;先前我們到官方下載或者國內鏡像直接可以下載到exe文件安裝&#xff0c;但是最近幾年qt官方似乎在逐漸關閉舊版本下載通道&#xff0c;列為不推薦下載。但是qt5以其廣泛使用和穩定性&#xff0c;以及積累大量代碼使得qt5…

Mysql架構理論部分

Mysql架構是什么&#xff1f;實際可以理解為執行一條sql語句所要經歷的階段有哪些&#xff01; 1.連接層 &#xff08;1&#xff09;客戶端發起連接 客戶端通過TCP/IP、Unix Socket或命名管道等方式向Mysql服務器發起鏈接請求 想要了解tcp與udp的區別&#xff0c;可以參考這…

架構師面試(十九):IM 架構

問題 IM 系統從架構模式上包括 【介紹人模式】和 【代理人模式】。介紹人模式也叫直連模式&#xff0c;消息收發不需要服務端的參與&#xff0c;即客戶端之間直連的方式&#xff1b;代理人模式也叫中轉模式&#xff0c;消息收發需要服務端進行中轉。 下面關于這兩類模式描述的…

【服務器】RAID0、RAID1、RAID5、RAID6、RAID10異同與應用

目錄 ?編輯 一、RAID概述 1.1 磁盤陣列簡介 1.2 功能 二、RAID級別 2.1 RAID 0&#xff08;不含校驗與冗余的條帶存儲&#xff09; 2.2 RAID1&#xff08;不含校驗的鏡像存儲&#xff09; 2.3 RAID 5 &#xff08;數據塊級別的分布式校驗條帶存儲&#xff09; 4、RAI…

MySQL身份驗證的auth_socket插件

在Ubuntu 20.04 LTS上&#xff0c;MySQL 8.0默認使用auth_socket插件進行身份驗證&#xff0c;可能存在意想不到的情況。 一、auth_socket插件 在使用sudo mysql或通過sudo切換用戶后執行任何MySQL命令時&#xff0c;不需要輸入密碼或錯誤密碼都可以正常登入mysql數據庫&…

小程序開發中的用戶反饋收集與分析

我們在開發小程序的過程中根據開發過程中的代碼及業務場景,以下是針對需求管理系統的用戶反饋收集與分析方案設計: 需求管理系統用戶反饋收集與分析方案 一、反饋數據模型設計 // 新增Feedback模型(app/admin/model/Feedback.php) namespace app\admin\model; use think\…

python關鍵字匯總

文章目錄 1. 變量與類型相關2. 控制流相關3. 函數與類相關4. 異常處理相關5. 模塊相關6. 其他 在 Python 3 里有 35 個關鍵字&#xff0c;它們各自具備特定的用途與意義 1. 變量與類型相關 True、False 意義&#xff1a;布爾類型的常量&#xff0c;分別代表邏輯真與邏輯假。示…

使用Python在Word中創建、讀取和刪除列表 - 詳解

目錄 工具與設置 Python在Word中創建列表 使用默認樣式創建有序&#xff08;編號&#xff09;列表 使用默認樣式創建無序&#xff08;項目符號&#xff09;列表 創建多級列表 使用自定義樣式創建列表 Python讀取Word中的列表 Python從Word中刪除列表 在Word中&#xff…

軟考-軟件設計師-計算機網絡

一、七層模型 中繼器&#xff1a;信號會隨著距離的增加而逐漸衰減&#xff0c;中繼器可以接受一端的信息再將其原封不動的發給另一端&#xff0c;起到延長傳輸距離的作用&#xff1b; 集線器&#xff1a;多端口的中繼器&#xff0c;所有端口公用一個沖突域&#xff1b; 網橋&…

關于Flask框架30道面試題及解析

文章目錄 基礎概念1. 什么是Flask?其核心特性是什么?2. Flask和Django的主要區別?3. 解釋Flask中的“路由”概念。如何定義動態路由?核心組件4. Flask的請求上下文(Request Context)和應用上下文(Application Context)有什么區別?5. 如何訪問請求參數?POST和GET方法的…

C++20 中 `constexpr` 的強大擴展:算法、工具與復數庫的變革

文章目錄 一、constexpr 在 <algorithm> 中的應用1. 編譯時排序2. 編譯時查找 二、constexpr 在 <utility> 中的應用1. 編譯時交換2. 編譯時條件交換 三、constexpr 在 <complex> 中的應用1. 編譯時復數運算 四、總結 C20 對 constexpr 的增強是其最引人注目…

【ELK】節省存儲 之 壓縮存儲方式調整

目錄 集群版本&#xff1a; 7.17.6 解釋幾個概念&#xff1a; 段&#xff08;Segment&#xff09; 合并(Merge) 索引設置&#xff1a; 壓縮方式(index.codec)&#xff1a; 測試設置前提條件 對比 在創建的時候指定壓縮類型&#xff08;index.codec&#xff09; 對比 在…