Spring MVC

1. 简介

  • M(Model)V(View)C(Controller),是一种软件设计规范
  • 将业务逻辑、数据、显示分离的方式来组织代码。
  • 降低视图业务逻辑间的双向耦合
  • SpringMVC是Spring Framework的一部分,基于Java实现MVC的轻量级Web框架
  • MVC不是一种设计模式,而是一种架构模式,当然不同的MVC存在差异
    注:
  1. 设计模式对在某种环境中反复出现的问题以及解决该问题的方案的描述,它比架构更抽象。
  2. 架构模式只是针对某一领域的具体实现,一个软件可能包含多种设计模式;而设计模式是一种思想,可适用于各种应用。
  3. 简单来说,框架是软件,而设计模式是软件的知识。

Model (模型)

数据模型,提供要展示的数据,因此包含数据和行为。
可以认为是领域模型或JavaBean组件(包含数据和行为) 。
不过现在一般都分离开来:Value Object (数据Dao)和服务层(行为Service) 。
也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。

View (视图):

负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。

Controller (控制器) :

接收用户请求,委托给模型进行处理(状态改变) ,处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。最典型的MVC就是JSP + servlet + javabean的模式。

  1. 用户发送请求。
  2. Servlet接收请求数据并调用对应的业务逻辑方法。
  3. 业务处理完毕返回更新的数据给Servlet。
  4. Servlet发送到JSP来渲染页面。
  5. 响应给前端更新后的页面。

特点

  1. 轻量级,简单易学
  2. 高效,基于请求响应的MVC框架
  3. 与Spring兼容性好,无缝结合
  4. 约定由于配置
  5. 功能强大:RESTful、数据验证、格式化、本地化、主题等
  6. 简洁灵活

2、MVC的演变历史

2.1、Model1

Model1时代
优点:架构简单,比较适合小型项目开发

缺点:JSP职责不单一,职责过重,不便于维护

2.2、Model2

Model1虽已在一定程度上解耦,但JSP即要负责页面控制,又要负责逻辑处理,职责不单一。于是Model2应运而生,使得各个部分各司其职。 Model2基于MVC模式:

Controller:控制器

  1. 取得表单数据
  2. 调用业务逻辑
  3. 转向指定的页面

Model:模型

  1. 业务逻辑
  2. 保存数据状态

View:视图

  1. 显示页面

Model2
优点:职责清晰,较适合于大型项目架构

缺点:分层较多,不适合小型项目开发

区别

	Model2 在 Model1 的基础上分离了控制,将JSP中的逻辑操作部分分离出来,这样做不仅减轻了JSP的职责,而且更有利于分工开发,耦合性降低。

2.3、三层

	Model2巧妙的将JSP中的业务逻辑部分分给了Servlet,使得页面控制与逻辑处理彻底分离,达到了部分解耦的目的。但我们现实项目开发中,
	往往在Model2的基础上又进行了分层。将业务逻辑细分为业务逻辑和持久化逻辑两层。
	
	往往使用一个Dao接口隐藏持久化操作的细节,业务对象不需要了解底层的数据库持久化知识。使得业务逻辑与持久化逻辑分离,
	业务逻辑通常关系的是应用程序的核心流程和业务规则,持久化逻辑关注的是如何访问和操作持久化数据。

三层

3、SpringMVC工作原理

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
  4. DispatcherServlet调用HandlerAdapter处理器适配器。
  5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServletModelAndView传给ViewReslover视图解析器。
  9. ViewReslover解析后返回具体View.
  10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet响应用户
    Spring MVC流程

4、Hello,SpringMVC(xml版)

4.1. 创建Maven工程,添加Web框架

在这里插入图片描述
在这里插入图片描述

4.2. 导入Maven依赖

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.2.0.RELEASE</version>
</dependency>
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
</dependency>
<dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.2</version>
</dependency>
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
</dependency>

4.3. 在resource目录下创建springmvc.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">
    <!--处理器映射器HandlerMapping-->
    <!--这个映射器会根据Bean名来找到Bean,实际开发一般不用-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

    <!--处理器适配器HandlerAdapter-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!--处理器Controller-->
    <bean id="/myController" class="com.qhit.controller.MyController"/>

    <!--视图解析器ViewResolver-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix"  value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

4.4. 在web.xml中配置DispatcherServlet

<!--SpringMVC核心,前端控制器,请求分发 -->
<servlet>
   <servlet-name>dispatcherServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet要绑定Spring配置文件-->
   <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>
<servlet-mapping>
   <servlet-name>dispatcherServlet</servlet-name>
   <!--/:表示拦截除jsp页面之别的所有请求-->
   <!--/*:拦截所有请求-->
   <url-pattern>/</url-pattern>
</servlet-mapping>

4.5、编写处理器,配置映射

package com.qhit.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 MyController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
         // 返回一个ModelAndView对象给HandlerAdapter
        ModelAndView mv = new ModelAndView();
        // 调用service层
        String result = "result";
        // 封装执行结果
        mv.addObject("result", result);
        // 封装跳转地址
        mv.setViewName("index");
        return mv;
    }
}
<!--处理器Controller-->
<bean id="myController" class="com.qhit.controller.MyController" />

4.6、配置Tomcat

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.7、可能遇到的问题

4.7.1、404

在这里插入图片描述

在这里插入图片描述
原因是jar包添加失败
接下来我们手动添加jar

  1. Shift+Control+Alt+S快捷键打开Project Structure
  2. 找到Artifacts,选中报错的项目,检查项目名,在WEB-INF下创建lib
    在这里插入图片描述

在这里插入图片描述
3. 选中lib,点击+号,选择Library Files库文件,选中要添加的jar,确认

在这里插入图片描述
在这里插入图片描述

4.7.2、库源与类DispatcherServlet的字节码不符

检查maven依赖

4.7.3、1099 is already in use

方案一:按快捷键 Ctrl+Shift+Esc 打开任务管理器,找到java.exe,然后点击“结束任务”即可!
在这里插入图片描述
方式二:这种方式适用于所有端口被占用的情况

  1. 通过端口找到PID
    打开dos命令行,输入netstat -ano | find “1099”,得到下列内容,看到最后一列是9280,就是PID:
    在这里插入图片描述
  2. 通过PID找到进程
    输入:tasklist | find “9280”(双引号里面的是PID)
    在这里插入图片描述
  3. 关闭进程
    输入命令关闭进程:taskkill /f /t /im java.exe
    在这里插入图片描述

5、Hello,SpringMVC(注解)

5.1、 新建项目,导入依赖

在这里插入图片描述

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.2.0.RELEASE</version>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.2</version>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
</dependency>

5.2、配置DispatcherServlet

<!--SpringMVC核心,前端控制器,请求分发 -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--DispatcherServlet要绑定Spring配置文件-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--启动级别为1,与服务器同生-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!--/:表示拦截除jsp页面之别的所有请求-->
    <!--/*:拦截所有请求-->
    <url-pattern>/</url-pattern>
</servlet-mapping>

5.3、配置springmvc.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: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">
    <!--自动扫描包,使包下注解生效,由IOC容器统一管理-->
    <context:component-scan base-package="com.qhit.controller"/>
    <!--设置SpringMVC不处理静态资源-->
    <mvc:default-servlet-handler/>
    <!---->

    <!--支持mvc注解驱动
    在spring中一般采用@RequestMapping注解来完成映射关系
    要想使@RequestMapping注解生效
    必须向上下文中注册
            DefaultAnnotationHandlerMapping、AnnotationMethodHandLerAdapter实例
    这两个实例分别在类级别和方法级别处理。
    而annotation-driven配置帮助我们自动完成上述两个实例的注入。-->
    <mvc:annotation-driven/>

    <!--视图解析器ViewResolver-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix"  value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

5.4、HelloController

package com.qhit.controller;

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

@Controller
@RequestMapping("/hello")  //访问地址:/项目名/hello
public class HelloController{

    //访问地址:/项目名/hello/h1
    @RequestMapping("/h1")
    public String hello(Model model){/* model:向前端传递数据 */
        model.addAttribute("msg", "hello, springmvc!");
		return "hello"; //view名称,会被视图解析器解析
    }
}

5.5、配置Tomcat,运行。如上

在这里插入图片描述

5.6、注解

@RestController
修饰类,方法直接返回JSON数据,跳过视图解析器
@ResponseBody
将java对象转为json格式的数据。
@Controller
控制层类注解,声明一个类是bean,放入IOC容器,相当于@Component
@PathVariable
加在控制器入参上,用于接收Restful风格的参数。

//访问地址:/项目名/hello/h1
    @RequestMapping(path = "/h1/{a}/{b}", method = RequestMethod.DELETE)
    @GetMapping //简化
    public String hello(@PathVariable int a,@PathVariable int b, Model model){/* model:向前端传递数据 */
        model.addAttribute("msg", "hello, springmvc!");
        return "hello"; //view名称,会被视图解析器解析
    }

6、Restful风格

Restful就是一个资源定位及资源操作的风格。
不是标准也不是协议。
基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

7、JSON

7.1、简介

  • JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
  • JSON 是轻量级的文本数据交换格式
  • JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。
  • JSON 具有自我描述性,更易理解

7.1.1、与 XML 的异同

    • JSON 是纯文本 JSON 具有"自我描述性"(人类可读)
    • JSON 具有层级结构(值中存在值)
    • JSON 可通过 JavaScript
    • 进行解析 JSON 数据可使用 AJAX 进行传输
    • 没有结束标签
    • 更短
    • 读写的速度更快
    • 能够使用内建的 JavaScript eval() 方法进行解析
    • 使用数组
    • 不使用保留字

7.1.2、为什么使用 JSON?

对于 AJAX 应用程序来说,JSON 比 XML 更快更易使用:
使用 XML

  • 读取 XML 文档
  • 使用 XML DOM 来循环遍历文档
  • 读取值并存储在变量中

使用 JSON

  • 读取 JSON 字符串
  • 用 eval() 处理 JSON 字符串

7.2、语法

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 大括号 {} 保存对象
  • 中括号 [] 保存数组,数组可以包含多个对象,例:
{
    "sites": [
	    { "name":"菜鸟教程" , "url":"www.runoob.com" }, 
	    { "name":"google" , "url":"www.google.com" }, 
	    { "name":"微博" , "url":"www.weibo.com" }
    ]
}

可以像这样访问 JavaScript 对象数组中的第一项(索引从 0 开始):

sites[0].name;

返回的内容是:

runoob

可以像这样修改数据:

sites[0].name="菜鸟教程";

7.3、JSON乱码问题

<!--JSON解决乱码问题-->
<mvc:annotation-driven>
   <mvc:message-converters>
       <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>

7.4、Jackson

7.4.1、maven依赖

<!--Jackson包-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>

7.4.2、Controller编写

package com.qhit.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController//Controller + ResponseBody
public class HelloController {
   
    //访问地址:/项目名/hello/h1
    @GetMapping(path = "/h1")
    //@ResponseBody // 返回值不会经过视图解析器,会直接返回字符串
    public String hello() throws JsonProcessingException {
        return new ObjectMapper().writeValueAsString(new User("1", "Candy"));
    }

    @GetMapping("h2")
    public String jsonDate() throws JsonProcessingException {
        ObjectMapper om = new ObjectMapper();
        //关闭时间戳(时间解析后的默认格式为:时间戳TimeStamp)
        om.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
        //定义时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        om.setDateFormat(sdf);
        return om.writeValueAsString(new Date());
    }
}

在这里插入图片描述

7.4、FastJSON

7.4.1、依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.60</version>
</dependency>

7.4.2、Controller编写

8、工具

Lombok

参考文献

框架和设计模式的区别 忘崖
浅析Java开发模式—Model1、Model2和三层 想太多先森

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值