SpringMVC(一)基本原理、使用、參數(shù)接收

MVC模式

MVC指的是模型(model)-視圖(view)-控制器(controller)模型,是一種用于設(shè)計創(chuàng)建Web應(yīng)用程序表現(xiàn)層的模式。可以將業(yè)務(wù)邏輯、數(shù)據(jù)、界面顯示代碼分離開來。

image.png
  • 三層架構(gòu)-mvc


    image.png

SpringMVC

SpringMVC是Spring產(chǎn)品對MVC模式的一種具體實現(xiàn),屬于輕量級的WEB框架,可以通過一套注解,讓一個簡單的Java類稱為控制器。而無須實現(xiàn)任何接口,同時還支持restful風(fēng)格


image.png

SpringMVC主要工作的組件有:

  • 前端控制器
  • 處理器映射器
  • 處理器適配器

SpringMVC入門案例

  • 加入坐標(biāo)
 <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>

        </dependency>


    </dependencies>
  • SpringMVC配置文件 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: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 http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--    配置注解掃描-->
    <context:component-scan base-package="com.itheima.controller"/>
    <!--    配置組件-->
    <!--    配置處理器映射器和處理器適配器-->
    <mvc:annotation-driven/>
    <!--    配置視圖解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
</beans>
  • web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--        配置參數(shù)-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!--        除了jsp不攔截-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  • 后端controller
@Controller
public class HelloController {
    @RequestMapping("/helloServlet/demo1")
    public String demo1() {
        System.out.println("hello1");
        return "/success.jsp";
    }
}
  • 請求頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/helloServlet/demo1">入門案例</a>

</body>
</html>
  • 響應(yīng)頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
Success
</body>
</html>

SpringMVC原理

image.png
  • 當(dāng)用戶通過瀏覽器發(fā)送一個請求會被前端控制器DispatcherServlet接收
  • DispathcerServlet接收請求后會調(diào)用處理器映射器HandlerMapper
  • HandlerMapper會找到具體的處理器鏈返回給DispatcherServlet
  • DispatcherServlet會根據(jù)收到返回的處理器鏈調(diào)用處理器適配器HandlerAdapter
  • HandlerAdapter經(jīng)過適配后會調(diào)用具體的Controller
  • Controller執(zhí)行完成后會返回一個執(zhí)行結(jié)果
  • HandlerAdapter將Handler的結(jié)果ModelAndView對象返還給DispatcherServlet
  • DispatcherServlet將ModelAndView對象傳給視圖解析器ViewReslover
  • ViewReslover解析后得到具體的View,并返回給DispatcherServlet
  • DispatcherServlet根據(jù)ViewReslover返回的View進(jìn)行視圖渲染。將模型數(shù)據(jù)填充到視圖中
  • DispathcerServlet會將渲染后的視圖響應(yīng)給瀏覽器

SpringMVC三大組件

  • 處理器映射器 HandlerMapper

根據(jù)請求中的URL尋找對應(yīng)的處理方法

  • 處理器適配器

真正的去調(diào)用處理方法

  • 視圖解析器

將邏輯視圖轉(zhuǎn)化成物理視圖

配置視圖解析器

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

RequestMapping

RequestMapping用于建立請求URL和處理方法之間的對應(yīng)關(guān)系,可以通過它的屬性對請求做出各種限制

  • value:用于限制請求URL(和path作用一樣),可以傳遞多個url @RequestMapping(value={url1,url2})
  • method:用于限制請求類型 get post 支持多個,如果不寫表示不做限制
  • Params:用于限制請求參數(shù)的條件 用于限制必傳參數(shù),支持?jǐn)?shù)組
@RequestMapping("/helloServlet/demo1")
    public String demo1() {
        System.out.println("hello1");
        return "success";
    }

此注解可以標(biāo)注在方法上,也可以標(biāo)注在類上,標(biāo)注在類上代表類中的所有方法都可以共用一段URL

限制請求路徑(value path)

  • 前臺頁面
<a href="${pageContext.request.contextPath}/helloServlet/demo2">指定請求路徑</a>

  • 后臺
@RequestMapping("/helloServlet/demo2")
    public String demo2() {
        System.out.println("指定請求路徑為:/helloServlet/demo2");
        return "success";
    }

限制請求類型(method)

限制只能是post方式請求,如果不是指定的請求方式 將會拋出405異常

  • 頁面
<form action="helloServlet/demo3" method="post">
    <input type="submit" value="限制請求方式">
</form>
  • 后臺
 @RequestMapping(value = "/helloServlet/demo3",method = RequestMethod.POST)
    public String demo3() {
        System.out.println("限制請求類型");
        return "success";
    }

限制請求參數(shù)(params)

  • 頁面
 <a href="${pageContext.request.contextPath}/helloServlet/demo4?name=zs">指定請求的參數(shù)</a>

  • 后臺

表示必須傳遞name參數(shù)

 @RequestMapping(value = "/helloServlet/demo4", params = "name")
    public String demo4() {
        return "success";
    }

接收請求參數(shù)

在SpringMVC中可以使用多種類型來接收前端傳入的參數(shù)

簡單類型

基本類型、基本類型的包裝類、字符串類型

只需要保證前端傳遞的參數(shù)名稱跟方法的形參名稱一致就好

  • 頁面
<a href="${pageContext.request.contextPath}/helloServlet/demo5?name=zs&age=18">接收簡單類型參數(shù)</a>

  • 后臺
@RequestMapping(value = "/helloServlet/demo5")
    public String demo5(String name, Integer age) {
        System.out.println("name = " + name);
        System.out.println("age = " + age);
        return "success";
    }

對象類型

只要保證前端傳遞的參數(shù)名稱和pojo的屬性名稱(set方法)一致

  • 前臺
<a href="${pageContext.request.contextPath}/helloServlet/demo6?name=ss&age=20">接收對象類型</a>

  • 后臺
 @RequestMapping("/helloServlet/demo6")
    public String demo6(User user) {
        System.out.println("user = " + user);
        return "success";
    }

數(shù)組類型

需要保證前端傳遞的參數(shù)名稱和方法中的數(shù)組形參名稱一致

  • 頁面
<a href="${pageContext.request.contextPath}/helloServlet/demo7?username=zz&username=zz2&username=zz3">傳遞數(shù)組類型</a>

  • 后臺
   @RequestMapping("/helloServlet/demo7")
    public String demo7(String[] username) {
        for (String s : username) {
            System.out.println(s);
        }
        return "success";
    }

集合類型

獲取集合類型的參數(shù)時,需要提供一個pojo對象,SpringMVC會將集合包裝到pojo對象中

  • 頁面
<form action="${pageContext.request.contextPath}/helloServlet/demo8" method="post">
    第一個user.name <input type="text" name="users[0].name"/><br/>
    第一個user.age <input type="text" name="users[0].age"/><br/>
    第二個user.name <input type="text" name="users[1].name"/><br/>
    第二個user.age <input type="text" name="users[1].age"/><br/>
    第三個user.name <input type="text" name="users[2].name"/><br/>
    第三個user.age <input type="text" name="users[2].age"/><br/>
    <input type="submit" value="傳遞集合"/>
</form>
  • 封裝vo對象
public class Vo {
    private List<User> users;
    private Map<String, String> map;

    @Override
    public String toString() {
        return "Vo{" +
                "users=" + users +
                ", map=" + map +
                '}';
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }
}
  • 后臺controller
 @RequestMapping("/helloServlet/demo8")
    public String demo8(Vo vo) {
        List<User> users = vo.getUsers();
        users.stream().forEach(user -> System.out.println(user));
        return "success";
    }

日期類型

對于一些常見的類型,SpringMVC是內(nèi)置了類型轉(zhuǎn)換器,也就是說在內(nèi)置中存在一個類型轉(zhuǎn)換器,可以自動轉(zhuǎn)換基本類型,但是對于一些類型的參數(shù),無法完成類型轉(zhuǎn)換。這時候就必須自定義類型轉(zhuǎn)換器了

  • 頁面
  • 自定義時間類型轉(zhuǎn)換器

    自定義類型轉(zhuǎn)換器需要實現(xiàn)Converter<S,D>接口

    • S:代表需要轉(zhuǎn)換的源Source類型
    • D:代表轉(zhuǎn)換后的目標(biāo)類型
public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        return new SimpleDateFormat("yyyy-MM-dd").parse(s);
    }
}
  • 配置類型轉(zhuǎn)換器 spring-mvc.xml

將自定義的類型轉(zhuǎn)換器注冊SpringMVC的轉(zhuǎn)換服務(wù),并且將服務(wù)注冊到注解驅(qū)動上

 <mvc:annotation-driven conversion-service="conversionService2"/>
    <!--    配置視圖解析器-->
    <!--    配置自定義類型轉(zhuǎn)換器-->
    <bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <!--                指定自定義類型轉(zhuǎn)換器-->
                <bean class="com.itheima.converters.DateConverter"/>
            </set>
        </property>
    </bean>
  • 后臺
  @RequestMapping("/helloServlet/demo9")
    public String demo9(Date date) {
        System.out.println(date);
        return "success";
    }

文件類型(文件上傳)

  • 配置文件上傳用的坐標(biāo)
<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
  • 配置文件上傳解析器

    <!--    配置文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="5242880"/>
    </bean>
    
  • 頁面

    • post提交
    • 多部分表單 part-form
    • type=file
<%--文件上傳--%>
<form action="${pageContext.request.contextPath}/helloServlet/demo10" method="post"
      enctype="multipart/form-data"
>
    <input type="file" name="upFile"/><br/>
    <input type="submit" value="上傳">
</form>
  • 后臺
@RequestMapping("/helloServlet/demo10")
public String demo10(MultipartFile upFile) throws IOException {
    //獲取名字 重新命名
    String newFileName = UUID.randomUUID() + upFile.getOriginalFilename();
    String saveFilePath = "/Users/wangxin/Documents/temp";
    File uploadFile = new File(saveFilePath, newFileName);
    //接收上傳文件
    upFile.transferTo(uploadFile);
    return "success";
}

多文件上傳

  • 頁面

多文件上傳 需要在<input type="file">標(biāo)簽中添加multiple屬性

多文件上傳:
<form method="post" action="${pageContext.request.contextPath}/helloServlet/demo11" enctype="multipart/form-data">
    <input type="file" multiple/>
    <input type="submit" value="提交">
</form>
  • 后臺 多文件上傳 后臺需要接收MultiPartFile數(shù)組
@RequestMapping("helloServlet/demo11")
public String demo11(MultipartFile[] upFiles) throws IOException {
    String saveFilePath = "/Users/wangxin/Documents/temp";

    for (MultipartFile file : upFiles) {
        String newFileName = UUID.randomUUID() + file.getOriginalFilename();
        File uploadFile = new File(saveFilePath, newFileName);
        //文件上傳
        file.transferTo(uploadFile);
    }
    System.out.println("文件上傳完畢");
    return "success";
}
文件上傳原理

在前端控制器(DispatcherServlet)有一個屬性叫做multipartResolver,它對應(yīng)著一個文件上傳解析器

當(dāng)SpringMVC啟動的時候,它就會在容器中尋找是否有一個id位multipartResolver的bean,如果有那么會將文件上傳的文件交給指定的文件解析器來做。

當(dāng)DispathcerServlet調(diào)用controller方法的時候就可以將MultipartFile作為參數(shù)傳進(jìn)去了

在Controller中就可以操作MultiPartFIle對象進(jìn)行文件的操作

接收參數(shù)的處理

中文亂碼

SpringMVC在使用POST提交請求時,對于中文參數(shù)會存在亂碼問題,我們可以使用SpringMVC提供的中文亂碼過濾器

  • 前端

通過form表單的post請求提交中文

<%--提交中文亂碼--%>
<br/>
<form action="${pageContext.request.contextPath}/helloServlet/demo12" method="post">
    姓名:<input type="text" name="username"/>
</form>

  • 配置 編碼過濾器
    <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>
  • 后臺

  • @RequestMapping("/helloServlet/demo12")
    public String demo12(String username) {
        System.out.println("接收到的參數(shù):" + username);
        return "success";
    }
    
@RequestParam

@RequestParam標(biāo)注在方法參數(shù)之前,用于對傳入的參數(shù)做一些限制,支持三個屬性:

  • Value:用于指定前端傳入的參數(shù)名稱
  • required:用于指定此參數(shù)是否必傳,默認(rèn)是true
  • defaultValue:當(dāng)參數(shù)為非必傳參數(shù)設(shè)置一個默認(rèn)值
  • 前臺
<a href="${pageContext.request.contextPath}/helloServlet/demo13?username=達(dá)到">前端參數(shù)對應(yīng)</a>

  • 后臺
 @RequestMapping("/helloServlet/demo13")
    public String demo13(@RequestParam("username") String name) {
        System.out.println(name);
        return "success";
    }

接收請求頭信息

接收請求頭,使用

  • @RequestHeader 前端控制器會將所有的請求頭封裝成一個Map結(jié)構(gòu)傳遞過來
  • @RequestHeader("key") 接收指定的請求頭
  • @CookieValue("key") 接收一個Cookie中的值
@RequestMapping("/helloServlet/demo14")
    public String demo14(
            @RequestHeader Map<String, String> headMap,
            @RequestHeader("cookie") String cookieKey,
            @CookieValue("JSESSIONID") String jSessionId
    ) {
        System.out.println(headMap);
        System.out.println(cookieKey);
        System.out.println(jSessionId);
        return "success";
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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