Spring MVC01

本文详细介绍了Spring MVC框架,从基本概念如MVC模型、Spring MVC的执行流程,到实际应用如HelloWorld程序、注解开发、响应传值、JSON支持,以及静态资源访问的配置,全方位解析Spring MVC的使用。
摘要由CSDN通过智能技术生成

1.简介

2.HelloWorld程序

3.Spring MVC的执行流程

4.对静态资源访问

5.注解的开发方式

6.响应传值

7.SpringMVC对JSON的支持

8.格式化JSON

 

一、简介

1.什么是MVC模型

       MVC模型:是一种架构型的模式,本身不引入新功能,只是帮助我们将开发的结构组织的更加合理,使展示与模型分离、流程控制逻辑、业务逻辑调用与展示逻辑分离------>责任分离。

       

       在CS架构标准的MVC中模型能主动推数据给视图进行更新(观察者设计模式,在模型上注册视图,当模型更新时自动更新视图),但在Web开发中模型是无法主动推给视图(无法主动更新用户界面),因为在Web开发是请求-响应模型。

2.什么是Spring MVC

       MVC框架,它解决WEB开发中常见的问题(参数接收、页面跳转 、文件上传、表单验证、国际化、等等),而且使用简单,与Spring无缝集成。

       Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架 (更安全,性能更好,更简单)。    

        支持 RESTful风格的 URL 请求 。    

        采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。

3.前端控制器

         Front Controller模式要求在WEB应用系统的前端(Front)设置一个入口控制器(Controller),所有的request请求都被发往该控制器统一处理,处理所有请求共同的操作。

二、HelloWorld程序

1、在pom.xml文件中添加依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
          http://maven.apache.org/xsd/maven-4.0.0.xsd">
         <modelVersion>4.0.0</modelVersion>

          <groupId>com.xj</groupId>
          <artifactId>SMvc</artifactId>
          <version>1.0.0</version>
          <packaging>war</packaging>

    <properties>
        <project.spring.verison>5.1.5.RELEASE</project.spring.verison>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${project.spring.verison}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${project.spring.verison}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${project.spring.verison}</version>
        </dependency>

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

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


</project>

2、配置控制器HelloController

package com.xj._01_hello;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

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

/**
 * Created by Administrator on 2019/12/30 0030.
 */
public class HelloController implements Controller{

    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {

        System.out.println("Hello SpringMVC!!!");

        ModelAndView mv = new ModelAndView();
        //跳转视图
        mv.setViewName("/hello.jsp");//将数据共享到前台页面
        mv.addObject("msg","你好");
        return mv;
    }
}

3、新建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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置控制器-->
    <bean name="/hello" class="com.xj._01_hello.HelloController"></bean>
</beans>

4、在web.xml文件中配置前端控制器

<web-app 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"
         version="3.0">

<!--配置前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--关联SpringMVC的配置文件-->
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:mvc.xml</param-value>
    </init-param>
    <!--Tomcat启动时完成初始化-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
      <!--通过访问什么路径的url,就可以进入前端控制器-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

5、hello.jsp

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2019/12/30 0030
  Time: 20:36
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    Spring MVC!!!
    ${msg}
</body>
</html>

启动Tomcat,访问hello.jsp

三、Spring MVC的执行流程

SpringMVC流程:

       01、用户发送出请求到前端控制器DispatcherServlet。

       02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。

       03、HandlerMapping找到具体的控制器(可查找xml配置或注解配置),生成处理器对象的执行链(如果有),再一起返回给DispatcherServlet。

      04、DispatcherServlet调用HandlerAdapter(处理器适配器)。

      05、HandlerAdapter经过适配调用具体的处理器(controller)。

      06、Controller执行完成返回ModelAndView对象。

      07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。

      08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。

      09、ViewReslover解析后返回具体View(视图)。

      10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

      11、DispatcherServlet响应用户。 

涉及组件分析:

       1、前端控制器DispatcherServlet(不需要程序员开发),由框架提供,在web.xml中配置。

             作用:接收请求,响应结果,相当于转发器,中央处理器。

       2、处理器映射器HandlerMapping(不需要程序员开发),由框架提供。

             作用:根据请求的url查找Handler(处理器/Controller),可以通过XML和注解方式来映射。

      3、处理器适配器HandlerAdapter(不需要程序员开发),由框架提供。

             作用:按照特定规则(HandlerAdapter要求的规则)去执行Controller。

      4、控制器Controller(需要工程师开发)

            注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。

            作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。

      5、视图解析器ViewResolver(不需要程序员开发),由框架提供

            作用:进行视图解析,把逻辑视图名解析成真正的物理视图。

            SpringMVC框架支持多种View视图技术,包括:jstlView、freemarkerView、pdfView等。

      6、视图View(需要工程师开发)

            作用:把数据展现给用户的页面 View是一个接口,实现类支持不同的View技术(jsp、freemarker、pdf等)

四、对静态资源的访问

         我们这样的配置有这样一个问题: 在Web根路径添加index.html,然后不能访问,原因是什么呢?为什么此时在配置前端控制器的URL模式(<url-pattern>)写成 / 就不行呢?

        

        

        原因:

        Tomcat中处理静态资源访问的servlet(default)的映射路径为/.

        在启动项目的时候,在Tomcat中的web.xml是先加载的,项目的web.xml是后加载的,如果配置了相同的映射路径,后面的会覆盖前者.

        也就是说,SpringMVC中的DispatcherServlet的映射路径覆盖了Tomcat默认对静态资源的处理的路径。

         如果SpringMVC要配置为/,那么就得设置Dispatcherservlet对静态资源进行支持。

         解决方案:需要在SpringMVC的配置文件中添加对静态资源的访问 <mvc:default-servlet-handler/>

         

          

          或者 /改成  *.do

         

        <mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet  的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 Tomcat默认的 Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet  继续处理

         /和/*的区别

        /  会匹配url请求/index等 ,也会匹配静态资源*.js,*.html等, 但不会匹配*.jsp文件。

        /* 会匹配url请求/index等 ,也会匹配静态资源*.js,*.html等,    会匹配*.jsp文件。如果使用JSP,直接响应JSP代码,没有渲染.(不建议)

        

五、注解的开发方式

1、配置前端控制器(参考上面)

2、配置控制器

package com.xj._02_anno;

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

/**
 * Created by Administrator on 2019/12/30 0030.
 */
@Controller
public class AnnoController {

    @RequestMapping("/list")
    public ModelAndView list(){
        System.out.println("这是注解的方式");
        return null;
    }
}

3、配置IoC和MVC注解解析器

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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">

    <!--配置控制器-->
    <bean name="/hello" class="com.xj._01_hello.HelloController"></bean>

    <!-- 配置对静态资源的访问-->
    <mvc:default-servlet-handler/>


    <!--IoC注解解析器-->
    <context:component-scan base-package="com.xj" />


    <!--MVC注解解析器-->
    <mvc:annotation-driven/>
</beans>

访问list页面,控制台输出

Java EE应用程序分为三层:

       控制层(Web)                           @Controller

       业务逻辑层(Service)               @Service

       数据持久层(DAO)                   @Resposotory

       其他组件使用通用注解           @Component

注意:  

       1):四者的功能一模一样,仅仅只是被贴的组件类型不同.    

       2):作用,就是把被贴的类交给Spring管理,创建出对象,如下.        

       <bean  id=”类简单名字,首字母小写”  class=”类的全限定名称”/>

SpringMVC注解的解析器: <mvc:annotation-driven>:

        会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter、ExceptionHandlerExceptionResolver三个bean。

        除此之外,还支持

               支持使用 ConversionService实例对表单参数进行类型转换.

               支持使用 @NumberFormat、@DateTimeFormat注解完成数据格式化操作.

               支持使用 @Valid注解对JavaBean实例进行JSR303验证.

               支持使用 @RequestBody和@ResponseBody注解读写JSON.

@RequestMapping注解: 设置Controller方法的访问URL,不能重名.

        一:URL路径映射           @RequestMapping("/list")

        二:窄化请求映射           @RequestMapping("employee/list")

        三:请求方法限定:          @RequestMapping(value="/list",method=RequestMethod.POST)

        假如多个类中,都有相同的list方法,就可以窄化请求映射

        如果一个类中有多个方法,可以将窄化请求提出来,在类中的上面添加@RequestMapping(/employee)

        

小结

        1.使用注解开发SpringMVC必须首先要配置mvc的注解解析器和IoC的注解解析器

        2.@RequestMapping注解用于指定对应的url请求路径,value的值表示路径,路径通常以"/"开头,"/"可以省略.

        3.@RequestMapping可以标注在类中,用于窄化请求映射.此时访问资源的路径为:"/类的路径/方法的路径"

        4.@RequestMapping可以添加method属性,用于限定请求请求后台资源的方法.

六、响应传值

情况一:Controller方法的返回值类型为void:

       此时就是把Controller当做Servlet来用(不用).

       在Controller方法形参上可以定义request和response,使用request或response指定响应结果:

            ①:使用request请求转发页面:     request.getRequestDispatcher("页面路径").forward(request, response);

            ②:通过response重定向页面:     response.sendRedirect("url")

            ③:通过response指定响应结果,例如响应json数据如下:     通过request.setAttribute("key","value")共享数据

package com.xj._03_response;

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

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

/**
 * Created by Administrator on 2019/12/30 0030.
 */
@Controller
public class ResponseController {

    @RequestMapping("/test1")
    public void test1(HttpServletRequest request, HttpServletResponse response) throws Exception{
        //共享数据
        request.setAttribute("msg","你好");
        //页面跳转
        request.getRequestDispatcher("/WEB-INF/view/response/response.jsp").forward(request,response);
    }

}
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2019/12/30 0030
  Time: 22:55
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    响应传值的页面!
    ${msg}
</body>
</html>

情况二:返回ModelAndView类型和共享数据(运用比较多).

        Controller方法中定义ModelAndView对象并返回,对象中设置model数据、指定view。

    @RequestMapping("/test2")
    public ModelAndView test2(){

        ModelAndView mv = new ModelAndView();

        //共享数据
        mv.addObject("msg","我不好");
        //默认的key为数据类型的首字母小写
        mv.addObject("为啥不好");
        //key值相同的数据,后一个会覆盖掉之前的数据
        mv.addObject(20);
        mv.addObject(30);

        //跳转页面
        mv.setViewName("/WEB-INF/view/response/response.jsp");

        return mv;
    }
 ${msg}${string}${integer}

重新配置视图解析器:

          Controller方法返回字符串表示逻辑视图名,通过视图解析器解析为物理视图地址。 此时默认的物理视图地址为:视图前缀+逻辑视图名称+视图后缀.

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--设置视图前缀-->
        <property name="prefix" value="/WEB-INF/view/"/>
        <!--设置视图后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
        //跳转页面
        mv.setViewName("response/response");

注:不适用于第一种情况

情况三:返回String类型和共享数据(使用广泛).

         返回值为String类型,即为逻辑视图名,此时默认视图的地址:前缀+方法的返回值+后缀

         使用参数中的Model对象共享数据:

    @RequestMapping("/test3")
    public String test3(Model model){
        model.addAttribute("msg","为啥好");
        return "response/response";
    }

  假如有一个User类

package com.xj._03_response;

/**
 * Created by Administrator on 2019/12/31 0031.
 */
public class User {
    private String name;
    private Integer age;

    public User(){}
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
        User user = new User();
        user.setName("张三");
        user.setAge(13);
        model.addAttribute(user);
${user}${user.age}

        redirect和forward: redirect和forward:  redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为重定向后的地址,不共享之前请求的数据。  forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址,共享之前请求中的数据。  redirect或者forward之后,配置的视图解析器中的前缀和后缀不再有效.

return "forward:hello.jsp";

return "redirect:hello.jsp";

情况四:返回对象类型和共享数据(把当前请求的url作为逻辑视图名称).

    //浏览器请求该方法时,会跳转到test.jsp页面(当前请求的url),
    //并将user对象共享到前台,共享的对象的默认key值为:简单类名,首字母小写
    @RequestMapping("/test4")
    public User test4(){
        return new User("李四",22);
    }

解决方法:  可以使用@ModelAttribute注解修改共享对象的key值

七、SpringMVC对JSON的支持

对象转换为json的方法有很多,可以使用工具类处理 有两种:

       一种是springMVC底层使用的jackson

       另外一个中为阿里出品,fastjson

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.6</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.6</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.6</version>
        </dependency>
    @RequestMapping("/test5")
    @ResponseBody   //可以把方法返回的对象,转成JSON格式的字符串,响应给方法的返回者
    public User test5(){
        return new User("王五",30);
    }

八、格式化JSON

假如有个Employee类有一些属性,但是不想显示password信息。

package com.xj._03_response;

import lombok.*;

import java.util.Date;

/**
 * Created by Administrator on 2019/12/31 0031.
 */
@Setter@Getter@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
    private Integer id;
    private String name;
    private Integer age;
    private Date birthday;
    private String password;
    private Boolean sex;
}
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
            <scope>provided</scope>
        </dependency>

解决方法:在实体类的属性上面添加注解

假如想更改属性的名字

假如想以日期的形式显示数据

假如不知道注解,解决方法,在实体类中添加一个方法如下

    public Map toJsonMap(){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        Map map = new HashMap();

        map.put("id",this.id);
        map.put("name",this.name);
        map.put("age",this.age);

        map.put("birthday",format.format(this.birthday));
        map.put("gender",this.sex);
        //password没写
        return map;
    }
    @RequestMapping("/test6")
    @ResponseBody   //可以把方法返回的对象,转成JSON格式的字符串,响应给方法的返回者
    public Object test6(){
        Employee employee = new Employee(1, "赵柳", 12, new Date(), "123", true);
        return employee.toJsonMap();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值