spring mvc 概述、配置及应用

spring mvc

它是用来开发基于 web 的应用程序。

流行的 mvc 框架

 struts 1.x
 webwork 
 struts 2.x (webwork+struts 1.x)  ssh  经常暴露安全问题
 springmvc 更容易上手,相对更安全

mvc 思想

model 模型 - 数据 domain
view 视图  - 数据的展现方式 jsp, jstl, el
controller 控制器 - 结合模型和视图,控制请求流程 servlet, controller

  • servlet 如果作为控制器

缺点1:请求参数处理麻烦 String 值 = request.getParameter("参数名")
缺点2:当业务比较多时,servlet 类的数量膨胀不好管理

  • controller 优点

优点:利用spring 各种思想,ioc, di, aop, 可扩展性高

spring mvc 使用步骤

1) 添加jar依赖

<!-- spring mvc 依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.21.RELEASE</version>
</dependency>

<!-- servlet, jsp, 标签库 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.2.1</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

2) 添加 spring 配置文件 spring.xml 在beans标签之中加入以下配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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"
       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/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
     
    <!-- 启用了 与 springmvc 相关的注解      
    @RestController
    @RequestMapping
    @ResponseBody
    @ExceptionHandler
    ...
    -->   
    <mvc:annotation-driven/>

    <!--扫描控制器类,需要管理的包名下的类,如:com.westos.controller-->
    <context:component-scan base-package="包名.类名"/>
    <!-- 配置视图的完整路径(前缀 和 后缀)  配置视图解析器-->
    <mvc:view-resolvers>
        <mvc:jsp prefix="/" suffix=".jsp"/>
    </mvc:view-resolvers>
</beans>

3) 添加控制器 web.xml文件中

 spring 提供的前控制器(实际是一个servlet),作为一个统一入口,由它来分发请求,进入真正的控制器,需要使用 web.xml 文件配置它的路径 。

<!-- 配置前控制器 (servlet) ,下面的两个name,随便什么名字都可以,但是要两个都相同-->
<servlet>
    <servlet-name>aa</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 指明 spring 配置文件的位置, 根据它创建 spring容器 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!-- tomcat 启动时, 就创建和初始化 servlet, 同时创建 spring 容器 -->
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>aa</servlet-name>
    <!-- / 用来匹配所有的路径 -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

 自己提供的控制器

@Controller
public class 控制器类 {

    @RequestMapping("请求路径") // 请求路径要唯一
    public String 方法1() {

    }

    ...

    @RequestMapping("请求路径")
    public String 方法n() {
        
    }

}

4) 配置视图

控制器方法的返回值是一个视图名,此视图名经过视图解析器解析为一个完整路径,利用请求转发跳转至该jsp。

<mvc:view-resolvers>
    <!-- 前缀 + 视图名 + 后缀 ==  完整路径, 再利用请求转发跳转至 jsp -->
    <mvc:jsp prefix="/" suffix=".jsp" />
</mvc:view-resolvers>

5) 处理请求参数

地址实例:http://localhost:8080/c1?name=zhangsan&age=18&birthday=1995-9-6

方法1: 只要把方法的参数名称和请求的参数名称对象,springmvc 会将请求参数的值赋值给方法参数,并完成类型转换
日期类型需要特殊处理,请求参数类型转换出错,会出现400错误, 日期可以使用 @DateTimeFormat(pattern="日期格式")

方法2:当请求参数较多时,可以把请求参数映射到java对象的属性上

class User{
    private String name;
    private Integer age;
    private Date birthday;
}

方法3:把参数信息包含在路径当中
删除用户

/deleteUser?id=1
/deleteUser?id=2

/deleteUser/1  删除1号用户
/deleteUser/2  删除2号用户

// 例如 /deleteUser/1  {id} 的值就是1     /deleteUser/2  {id} 的值就是2
@RequestMapping("/deleteUser/{id}")
// @PathVariable 获取一个路径变量的值{id}, 然后复制给方法参数
public String c4(@PathVariable("id") int aa) {
    System.out.println("值为:" + aa);
    return "hello";
}

6) 处理模型数据

Model接口, 需要调用Model 的相关方法把数据存入模型,页面上再从模型中获取数据并显示。

.addAttribute("名字", 对象);  // 将数据加入 Model

原理:会把模型中数据放入request作用域

使用传统 servlet 中的类

HttpServletRequest, HttpServletResponse, HttpSession 他们都可以作为控制器方法的参数,直接使用即可,spring会把他们准备好

代码演示

1、使用springmvc的例子

控制类,也可以说这个类是用来定义页面的地址,以及控制页面跳转的类

import org.springframework.format.annotation.DateTimeFormat;
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.servlet.ModelAndView;

import java.util.Arrays;
import java.util.Date;

// 表示它是一个控制器类, 并且配合扫描交给 spring 容器管理
@Controller
public class HelloController {

    // 在web 的请求路径和 java 代码之间建立映射关系, 以方法为单位映射
    @RequestMapping("/c1")
    public String a1(String name, Integer age,@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) {
        System.out.println("执行了 a1 方法: name:" + name + " age:" + age + " birthday:" + birthday);
        return "hello";
        // 返回值代表视图的名字,但要注意它不是完整路径
        // /hello.jsp
    }

    @RequestMapping("/c2")
    public String a2() {
        System.out.println("执行了 a2 方法");
        // 没有经过视图解析器,直接转发进行了跳转
        return "forward:/hello.jsp";
    }

    @RequestMapping("/c3")
    public String c3(User user) {
        System.out.println(user);
        return "hello";
    }

    // 例如 /deleteUser/1  {id} 的值就是1 /deleteUser/2  {id} 的值就是2
    @RequestMapping("/deleteUser/{id}")
    // @PathVariable 获取一个路径变量的值{id}, 然后复制给方法参数
    public String c4(@PathVariable("id") int aa) {
        System.out.println("值为:" + aa);
        return "hello";
    }

    // model 不需要自己创建, 只需要在控制器方法上声明一个 Model 类型的参数, spring 会帮我们创建好
    @RequestMapping("/c5")
    public String c5(Model model) {
        model.addAttribute("name", "张三");
        model.addAttribute("list", Arrays.asList("苹果","草莓","橘子"));
        return "model";
    }
    // 跳转至 jsp 视图之前, springmvc 会把 model 中的每一项数据存入 request作用域
    /*
        如下存入:
        request.setAttribute("name", "张三");
        request.setAttribute("list", Arrays.asList("苹果","草莓","橘子"));
     */

    @RequestMapping("/c6")
    // 控制方法的返回值代表 视图名, Model 代表的是模型,用来存储数据
    public ModelAndView c6() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("name", "张三");
        mav.addObject("list", Arrays.asList("苹果","草莓","橘子"));
        //在对象中存入要跳转的视图的名字,也就是jsp页面的名字
        mav.setViewName("model");
        return mav;
    }
}

hello.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
进入了hello.jsp
</body>
</html>

model.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</title>
</head>
<body>
    <!--从作用域中拿到值,用el表达式来取值-->
    ${name}
    <hr>
    <ul>
    <c:forEach items="${list}" var="a">
        <li>${a}</li>
    </c:forEach>
    </ul>
</body>
</html>

结果

下面是都是服务器上输出的结果(地址为:/c1、/c2、/c3、/deleteUser/{id} 的结果),它们都会跳转到hello.jsp页面,如下图:

//在地址栏输入 localhost:8080/c1?name=zhangsan&age=18&birthday=1995-9-6 时服务器结果如下结果如下
执行了 a1 方法: name:zhangsan age:18 birthday:Wed Sep 06 00:00:00 CST 1995

//输入 localhost:8080/c2 时,服务器输出结果如下
执行了 a2 方法

//输入localhost:8080/c3?name=jack 时,服务器输出的结果如下
User{name='jack', age=null, birthday=null}

//输入localhost:8080/deleteUser/3 时,服务器输出的结果如下
值为:3

当输入的地址是  /c5 或 /c6 时结果如下图所示:

2、使用传统 servlet 中的类例子

控制类

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Controller
public class ServletController {
    @RequestMapping("/s1")
    public String s1(HttpServletRequest request,HttpServletResponse response,HttpSession session) {
        //session作用域中存入值,返回给视图servlet.jsp
        session.setAttribute("name", "老王");
        return "servlet";
    }
}

servlet.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <!-- page 找, request 找, session 找, application 找  会依次查找4个作用域,直到找到-->
    ${ sessionScope.name }
</body>
</html>

结果

总结

在 sping mvc 中运用注解的方式把代码放到容器中管理,减少了很多配置和代码的书写,用过它可以很简单的与jsp进行交互,不用在写繁琐的servlet代码,可以说是大大地好啦!!!

简而言之,加油吧!!!好好学习天天向上!!!

猜你喜欢

转载自blog.csdn.net/grey_mouse/article/details/87741707