SpringMVC 简介与入门教程

SpringMVC 简介

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 Spring

SpringMVC 简介与入门教程

FrameWork 的后续产品,已经融合在 Spring Web Flow 里面。


SpringMVC 优势:

1、清晰的角色划分:
前端控制器(DispatcherServlet)
请求到处理器映射(HandlerMapping)
处理器适配器(HandlerAdapter)
视图解析器(ViewResolver)
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command  请求参数绑定到的对象就叫命令对象)
表单对象(Form Object  提供给表单展示和提交到的对象就叫表单对象)。
2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
3、由于命令对象就是一个  POJO,无需继承框架特定  API,可以使用命令对象直接作为业务对象。
4、和  Spring  其他框架无缝集成,是其它  Web  框架所不具备的。
5、可适配,通过  HandlerAdapter  可以支持任意的类作为处理器。
6、可定制性,HandlerMapping、ViewResolver  等能够非常简单的定制。
7、功能强大的数据验证、格式化、绑定机制。
8、利用  Spring  提供的  Mock  对象能够非常简单的进行  Web  层单元测试。
9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10、强大的  JSP  标签库,使  JSP  编写更容易。
………………还有比如 RESTful 风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
置支持等等。

SpringMVC 配置

坐标依赖

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

web.xml

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!--   配置前端控制器 servlet 跟 mapping-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--  配置 Servlet 的初始化参数,读取 springmvc 的配置文件,创建 spring 容器  -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--  配置 servlet 启动时加载对象   而不是请求时候才加载  -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!--    / 表示所有请求都经过它 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

springmvc.xml 配置文件

该 xml 文件名称可自定义,需要在 web.xml 中指定,详见上方 web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
    <!--     配置所需要的名称空间后   配置注解扫描 -->
    <context:component-scan base-package="com.cheng"></context:component-scan>
    <!--  配置视图解析器  -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--         配置视图解析器解析的前缀目录 -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!--         配置解析的后缀   下列也就是只解析到 jsp 文件 -->
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!--     配置 spring 开启注解 mvc 的支持   该注解包含 SpringMVC 中的其他处理器 -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

<mvc:annotation-driven /> 解析

用   自动加载 RequestMappingHandlerMapping(处理映射器)和 RequestMappingHandlerAdapter ( 处理适配器 ),如果不使用这种写法,可以使用下列配置,下载配置其实就是细化,可让你根据适合场景使用适合的处理器,而非全部加载。

    <!-- Begin -->
    <!-- HandlerMapping -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <!-- HandlerAdapter -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
    <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
    <!-- HadnlerExceptionResolvers -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>
    <bean class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver"></bean>
    <bean class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"></bean>
    <!-- End -->

小流程

启动 Tomcat-> 加载 web.xml-> 由于配置 load-on-startup 启动即创建前端控制器 -> 加载 springmvc.xml-> 开启注解扫描 -> 扫描 @Controller 注解的类创建对象

前端 jsp 页面发请求 -> 到前端控制器 -> 根据 @RequestMapping 找具体方法执行 -> 根据方法返回结果 -> 根据视图解析器 -> 查找指定的页面 ->Tomcat 渲染页面 -> 响应给页面

常用注解

@RequestMapping

作用:建立请求 URL 与方法之间对应关系。

写法:可以写在类与方法上,value 值为 / 表示根目录

属性:

  1. path/value   指定请求路径的 url 例:@RequestMapping(path ="/hello")、@RequestMapping(value="/hello") 其中如果只有 value 一个属性的话可以省略不写,即 @RequestMapping("/hello")

  2. mthod 指定该方法的请求方式

    @RequestMapping(value="/saveAccount",method=RequestMethod.POST)
    可以配置多种方式,在 {} 中写
  3. params 指定限制请求参数的条件

    RequestMapping(value="/remove",params= {"accountName","money>100"})
    // 限制传来参数中必须有 accountName、money 参数,money 还需要 >100
  4. headers 发送的请求中必须包含的请求头

    RequestMapping(value="/remove",header= {"Accept"})
    // 限制 header 中必须有 Accept

在 jsp 中可以采用绝对与相对 URL 访问 mapping

<a href="${pageContext.request.contextPath}/account/findAccount"> 绝对 </a>
<a href="account/findAccount"> 相对 </a>
${pageContext.request.contextPath}取的是虚拟目录的名称 

@RequestParam

与前台传递参数不一致,用它进行与形参关联,例如下列前台传的参数 username,但后台必须用 name 时

public String sayHello(@RequestParam(value="username",required=false)String name) {}

@RequestBody

用于获取请求体的内容(注意:get 方法不适用,适用于 post 或 ajax 异步请求)

required:是否必须有请求体,默认值是 true

public String sayHello(@RequestBody String body) {}

@PathVariable

拥有绑定 url 中的占位符的。例如:url 中有 /delete/{id},{id}就是占位符

<a href="user/hello/1"> 入门案例 </a>
/**
*  接收请求
* @return
*/
@RequestMapping(path="/hello/{id}")
public String sayHello(@PathVariable(value="id") String id) {System.out.println(id);
	return "success";
}

Restful 风格的 URL

  1. 请求路径一样,可以根据不同的请求方式去执行后台的不同方法

  2. restful 风格的 URL 优点

    1. 结构清晰

    2. 符合标准

    3. 易于理解

    4. 扩展方便

@RequestHeader

获取指定请求头的值

public String sayHello(@RequestHeader(value="Accept") String header) {}

@CookieValue

获取指定 cookie 的名称的值

@RequestMapping(path="/hello")
public String sayHello(@CookieValue(value="JSESSIONID") String cookieValue) {System.out.println(cookieValue);
	return "success";
}

@ModelAttribute

  1. 出现在方法上:表示当前方法会在控制器方法执行前线执行。

  2. 出现在参数上:获取指定的数据给参数赋值。

应用场景:当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。

    /**
     * 假设 User 对象中有 name 跟 password 字段,前端只传了 name
     *  要知道 password  第一种在该 Controller 中写读数据库操作
     *  第二种在 @ModelAttribute 修饰的方法中写数据库操作   因为它优先执行
     */
    @RequestMapping(path = "/updateUser")
    public String updateUser(User user) {        System.out.println(user);
        return "success";
    }

    /**
     *  作用在方法,先执行
     *  通过前端传的 name 查询 password 并返回给 user
     */
    @ModelAttribute
    public User showUser(String name) {        System.out.println("showUser 执行了...");
//  模拟从数据库中查询对象, 此处为演示直接设置对象属性
        User user = new User();
        user.setName(" 哈哈 ");
        user.setPassword("123");
        return user;
    }

假设 @ModelAttribute 修饰的先行方法没返回值怎么办?可在方法参数中加合适类型 Map,然后将数据库查询的对象 put 进去,在需要的 Controller 方法的参数上再加 @ModelAttribute 注解把值再赋给 user

    @RequestMapping(path = "/updateUser")
    public String updateUser(@ModelAttribute(value = "abc") User user) {        System.out.println(user);
        return "success";
    }
    
    @ModelAttribute
    public void showUser(String name, Map<String, User> map) {        System.out.println("showUser 执行了...");
//  模拟从数据库中查询对象
        User user = new User();
        user.setName(" 哈哈 ");
        user.setPassword("123");
        map.put("abc", user);
    }

@SessionAttributes

用于多次执行控制器方法间的参数共享。只能写在类上。

@Controller
@RequestMapping(path = "/user")
@SessionAttributes(value = {"username", "password", "age"}, types =
        {String.class, Integer.class}) //  把数据存入到 session 域对象中
public class HelloController {
    /**
     *  向 session 中存入值
     *
     * @return
     */
    @RequestMapping(path = "/save")
    public String save(Model model) {        System.out.println(" 向 session 域中保存数据 ");
//         会向 Request 域中添加数据
//         加 SessionAttributes 注解会再次向 Session 域中
        model.addAttribute("username", "root");
        model.addAttribute("password", "123");
        model.addAttribute("age", 20);
        return "success";
    }

    /**
     *  从 session 中获取值
     *
     * @return
     */
    @RequestMapping(path = "/find")
    public String find(ModelMap modelMap) {
//        ModelMap 是 Model 的实现类,可以取数据
        String username = (String) modelMap.get("username");
        String password = (String) modelMap.get("password");
        Integer age = (Integer) modelMap.get("age");
        System.out.println(username + " : " + password + " : " + age);
        return "success";
    }

    /**
     *  清除值
     *
     * @return
     */
    @RequestMapping(path = "/delete")
    public String delete(SessionStatus status) {
//         将 session 状态设置为完成则清除 session
        status.setComplete();
        return "success";
    }
}

参数绑定

1、传什么接收什么

<a href="account/findAccount?accountId=10"> 查询账户 </a>
后端:
public String findAccount(Integer accountId){}

2、实体类

User 实体类中有 name 跟 age 属性,前台传 uname、age,后台用实体类直接接收
后台:
public String findAccount(User user){}

3、关联实体类(类中有类), 例如 Account 类中含 User 类:

public class Account implements Serializable{
    private String username;
    private String password;
    private Double money;
    private User user;
    ...
    }

那它前端就是:

<form action="param/saveAccount" method="post">
         姓名:<input type="text" name="username" /><br/>
         密码:<input type="text" name="password" /><br/>
         金额:<input type="text" name="money" /><br/>
         用户姓名:<input type="text" name="user.uname" /><br/>
         用户年龄:<input type="text" name="user.age" /><br/>
        <input type="submit" value=" 提交 " />
 </form>

4、数组和集合类型参数,实体类中包含 List 于 Map

    <form action="param/saveAccount" method="post">
         姓名:<input type="text" name="username" /><br/>
         密码:<input type="text" name="password" /><br/>
         金额:<input type="text" name="money" /><br/>

         用户姓名:<input type="text" name="list[0].uname" /><br/>
         用户年龄:<input type="text" name="list[0].age" /><br/>

         用户姓名:<input type="text" name="map['one'].uname" /><br/>
         用户年龄:<input type="text" name="map['one'].age" /><br/>
        <input type="submit" value=" 提交 " />
    </form>

过滤器解决中文乱码

Get 情况下乱码

web.xml 中加入:

    <!--  配置过滤器,解决中文乱码的问题  -->
    <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>
         <!--  启动过滤器   可不加 -->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在 springmvc.xml 中可以配置静态资源不过滤

<!-- location  表示路径,mapping  表示文件,** 表示该目录下的文件以及子目录的文件  -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/scripts/" mapping="/javascript/**"/>

Post 情况下乱码

tomacat  对  GET  和  POST  请求处理方式是不同的,GET  请求的编码问题,要改  tomcat  的  server.xml
配置文件,如下:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"/>
改为:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"
useBodyEncodingForURI="true"/>
如果遇到  ajax  请求仍然乱码,请把:
useBodyEncodingForURI="true" 改为  URIEncoding="UTF-8"

HiddentHttpMethodFilter

由于浏览器 form 表单只支持 GET 与 POST 请求,而 DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法,使得支持 GET、POST、PUT   与 DELETE 请求。

使用方法:

第一步:在 web.xml 中配置该过滤器。

第二步:请求方式必须使用 post 请求。

第三步:按照要求提供_method 请求参数,该参数的取值就是我们需要的请求方式。

 <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>

此时,前端就要改成如下:

		<!--  保存  -->
		<form action="springmvc/testRestPOST" method="post">
			用户名称:<input type="text" name="username"><br />
			<!-- <input type="hidden" name="_method" value="POST"> -->
			<input type="submit" value=" 保存 ">
		</form>
		<hr />
		<!--  更新  -->
		<form action="springmvc/testRestPUT/1" method="post">
			用户名称:<input type="text" name="username"><br />
			<input type="hidden" name="_method" value="PUT">
			<input type="submit" value=" 更新 ">
		</form>

说白了就是在表单中加入了

<input type="hidden" name="_method" value="PUT">

持续更新中……

目录
  • SpringMVC 简介
  • SpringMVC 配置
    • 坐标依赖
    • web.xml
    • springmvc.xml 配置文件
      • <mvc:annotation-driven /> 解析
      • 小流程
  • 常用注解
    • @RequestMapping
    • @RequestParam
    • @RequestBody
    • @PathVariable
      • Restful 风格的 URL
    • @RequestHeader
    • @CookieValue
    • @ModelAttribute
    • @SessionAttributes
  • 参数绑定
  • 过滤器解决中文乱码
    • Get 情况下乱码
    • Post 情况下乱码
  • HiddentHttpMethodFilter
  • 目录
  • SpringMVC 简介
  • SpringMVC 配置
    • 坐标依赖
    • web.xml
    • springmvc.xml 配置文件
      • <mvc:annotation-driven /> 解析
      • 小流程
  • 常用注解
    • @RequestMapping
    • @RequestParam
    • @RequestBody
    • @PathVariable
      • Restful 风格的 URL
    • @RequestHeader
    • @CookieValue
    • @ModelAttribute
    • @SessionAttributes
  • 参数绑定
  • 过滤器解决中文乱码
    • Get 情况下乱码
    • Post 情况下乱码
  • HiddentHttpMethodFilter
  • 手机扫描二维码访问

    本文标题:《SpringMVC 简介与入门教程》作者:极四维博客
    原文链接:https://cway.top/post/544.html
    特别注明外均为原创,转载请注明。

    分享到微信

    扫描二维码

    可在微信查看或分享至朋友圈。

    相关文章

    极四维博客 极四维博客 发布于 2019-08-22 18:00:08  
    @RequestParam Map params也可以接受x-www-form-urlencoded方式的数据 回复
    极四维博客极四维博客 上述参数为map集合,post格式发送;当然这种与get方式直接拼接发送结果一致 回复
    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    «    2024年10月    »
    123456
    78910111213
    14151617181920
    21222324252627
    28293031

    搜索

    控制面板

    您好,欢迎到访网站!
      查看权限

    最新留言

    文章归档

    • 订阅本站的 RSS 2.0 新闻聚合