SpringMVC

SprintMVC#

框架学习:官方文档

重点:SprintMVC的执行流程

1.回顾MVC#

MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。

  • Model(dao,service)

    是核心的"数据层"(Model),也就是程序需要操作的数据或信息。

  • View(jsp..)

    直接面向最终用户的"视图层"(View)。它是提供给用户的操作界面,是程序的外壳。

  • Controller(servlet)

    它负责根据用户输入的指令,选取"数据层"中的数据,然后对其进行相应的操作调用"视图层,产生最终结果。

mvc要做的事#

1.将url映射到java类

2.封装用户提交的数据

3.处理请求-调用model-封装响应数据

4.渲染响应数据

2.初识SpringMVC#

Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就已包含在Spring Framework中。

优点:

  • 轻量级,简单易学

  • 高效,基于请求响应的MVC框架

  • 与Spring无缝结合

  • 约定大于配置

  • 功能强大:restful,数据验证,格式化,本地化,主题等等

与其他许多Web框架一样,Spring MVC围绕前端控制器模式DispatcherServlet进行设计,在该模式下,中央Servlet DispatcherServlet提供了用于请求处理的共享算法,而实际工作是由可配置的委托组件执行的。 该模型非常灵活,并支持多种工作流程。

image-20200802125954379

DispatcherServlet#

SpringMVC的核心就是DispatcherServlet,DispatcherServlet实质也是一个HttpServlet。DispatcherSevlet负责将请求分发,所有的请求都有经过它来统一分发。

DispatcherServlet 与任何Servlet一样,都需要使用Java配置或在web.xml中根据Servlet规范声明和映射DispatcherServlet。

反过来,DispatcherServlet使用Spring配置发现请求映射,视图解析,异常处理等所需的委托组件。

image-20200802102523663

代码实现#

1.配置DispatcherServlet 在web.xml#

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

<!--  配置DispatcherServlet-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--    关联配置文件 springmvc-servlet.xml-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
<!--    设置启动级别-->
    <load-on-startup>1</load-on-startup>
  </servlet>

<!--  / 拦截所以请求 除了jsp-->
<!--  /* 拦截所以请求 加上jsp-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

2.配置springmvc容器springmvc-servlet.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:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!--     处理映射器-->
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--     处理适配器-->
    <bean  id="handlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

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

<!--    注册controller-->
    <bean id="/hello"  class="com.cb.Controller.MyController"/>

</beans>

3.写controller#

package com.cb.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 httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //视图和模型
        ModelAndView model = new ModelAndView();
        //添加对象
        model.addObject("msg","hello springmvc");
        //添加视图名字
        model.setViewName("hello");

        return model;
    }
}

3.springMVC执行流程#

image-20200802130118065

处理器:是对控制器的封装

HandlerMapping:代表请求路径和控制器(或其方法)的映射关系,它会在 Web 务器启动 Spring MVC 时,就被扫描到HandlerMapping 的机制中存储,

HanderExecutionChain 对象:HandlerExecutionChain 对象包含一个处理器( handler 这里的处理器是对控制器( controller )的包装,因为我们的控制器方法可能存在参数,那么处理器就可以读入 HTTP和上下文的相关参数,然后再传递给控制器方法。而在控制器执行完成返回后,处理器又可以通过配置信息对控制器的返回结果进行处理。

HanderAdapter

但是我们有普通 HTTP 请求,也有按 BeanName 的请求,甚至是 WebSocket 的请求,所以它还需要 个适配器去运行 HandlerExecutionChain 对象包含的处理器,这就是 HandlerAdapter 接口定义的实现类

分析流程:#

  1. DispatcherServlet代表前端控制器,接受前端请求并拦截请求,调用HanderMapping

  2. 用户发起请求被 DispatcherServlet 拦截后,通过URL和其他的条件 ,通过HandlerMapper机制就能找到对应的控制器(或其方法)进行响应。只是通 HandlerMapping 返回的 是一个HanderExecutionChain 对象。

  3. 通过HanderAdapter对象:执行 Web 请求的 HandlerExecutionChain 对象包含的内容,这样就能

    够执行我们的处理器( handler 了。

  4. 在处理器调用控制器时,它首先通过模型层得到数据,再放入数据模型中,最后将返回模型和视图( ModelAndView )对象,这里控制器设置的视图名称设置为“xxxx ”,这样就走到了视图解析器 ViewResolver ),去解析视图逻辑名称了。

  5. DispatcherServlet 再调用视图,将数据模板渲染展示。

4.使用注解开发SpringMVC#

1.修改springmvc-servlet.xml文件#

<!--    //开启注解扫描  @Controller-->
    <context:component-scan base-package="com.cb.Controller"/>

<!--  annotation-driven 开启注解驱动,让@requestMapping注解生效
      并且自动注入 requestHandermappong  和 handerAdapter ,两个类是让@requestMapping注解生效的前提
-->
    <mvc:annotation-driven/>

<!--    处理静态资源  让springmvc不处理静态支援-->
    <mvc:default-servlet-handler/>

2.使用注解#

@Controller

@RequestMapping("/hello")

package com.cb.Controller;

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

@Controller
public class MyController  {

    @RequestMapping("/hello")
    public String handleRequest() {
        //视图和模型
        ModelAndView model = new ModelAndView();
        //添加对象
        model.addObject("msg","hello springmvc");

        return "hello";
    }
}

使用springMVC必须配置三大件:

  • HandlerMapping

  • HanderAdapter

  • ViewResolver

5.restful风格#

Representational State Transfer

RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,以使用XML格式定义或JSON格式定义。

RESTFUL特点包括:

1、每一个URI代表1种资源;

2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源; patch方法用来更新局部资源

3、通过操作资源的表现形式来操作资源;

4、资源的表现形式是XML或者HTML;

5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息'

Spring对RESTful的支持#

- Spring MVC 对 RESTful应用提供了以下支持

- 利用@RequestMapping 指定要处理请求的URI模板和HTTP请求的动作类型

- 利用@PathVariable讲URI请求模板中的变量映射到处理方法参数上

- 利用Ajax,在客户端发出PUT、DELETE动作的请求

代码实现#

@GetMapping("/userr/{id}")
public String handleRequest(@PathVariable(value = "id")int id1) {
    System.out.println(id1);
    //视图和模型
    ModelAndView model = new ModelAndView();
    //添加对象
    model.addObject("msg","hello springmvc");

    return "hello";
}

6.重定向和请求转发#

请求转发#

return "forward:/hello";
return model ;
return "x.jsp"

重定向#

return "redirect:/hello";

7、接受请求参数#

1.请求参数和方法参数名字一致#

则直接可以接受

2.请求参数和方法参数名字不一致#

使用@RequestParam

3.请求参数是一个对象#

前端使用表单,用一个pojo接受,即用一个对象接收,要求对象属性和表单域名一致

请求参数传递接受#

# 请求参数 
	如果没有传递 为null  
	http://localhost:8989/user/demo?name  传递为''

json#

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

前端解析#

<script type="text/javascript">

    var user = {
        name:"chen",
        age:12
    }

    //对象转换为json字符串
    var str = JSON.stringify(user);
    console.log(str)
    //把json字符串转化为对象
    var user1 = JSON.parse(str);
    console.log(user1)


</script>

后台解析json#

1.导入包#

<!--        json转换-->
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.0</version>
        </dependency>

2.配置乱码问题#

<!--Jackson乱码解决-->
<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>

3.使用Jackson解析#

@RestController
public class JsonController {

    @RequestMapping("/j1")
    public String get1() throws JsonProcessingException {

        User user = new User("张山","男",20);
        User user2 = new User("张山2","男",20);
        User user3 = new User("张山3","男",20);

        List<User> list = new ArrayList<>();
        list.add(user);
        list.add(user2);
        list.add(user3);

        ObjectMapper objectMapper = new ObjectMapper();
        String s = objectMapper.writeValueAsString(list);

        return s;
    }
}

使用fastjson

image-20200804091926355

4.简单开发#

@RestController  =  
@Controller
@ResponseBody  //标记返回json

使用@RestController 就会自动解析成json返回

解析json数据#

参考

@RequestBody#

作用:

主要用来接收前端传递给后端json字符串中的数据的(请求体中的数据的);

要求:

GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。

在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

简言之:

一个请求——》只有一个@RequestBody;

一个请求——》可以有多个@RequestParam。

9、拦截器#

(1)过滤器:

依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

(2)拦截器:

依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。

自定义拦截器#

1.继承一个接口HandlerInterceptor#

package com.cb.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor implements HandlerInterceptor {

    public MyInterceptor() {
        super();
    }
	
    
    //返回false 就不向下执行了
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

//执行结构:
 //   preHandle
//postHandle
//afterCompletion


2.注册拦截器#

<mvc:interceptors>
        
        <mvc:interceptor>
<!--            /* 表示一个目录下的所有  /** 表示下面的所有-->
            <mvc:mapping path="/**"/>
            <bean class="com.cb.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

10.文件上传#

SpringMVC很好的处理了文件上传,但是SpringMVC上下文默认没有装配MultipartResolver,因此默认不能进行文件上下传处理。需要处理文件需要配置。

前端表单要求:

​ 表单的method必须为为post,enctype=“multipart/form-data”,这样才能浏览器才能把用户选择的文件以二进制数据发送给服务器。

image-20200804171250106

1.引入依赖#

fileupload - servlet

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
和servlet

2.前端文件#

<%--
  Created by IntelliJ IDEA.
  User: 他知道
  Date: 2020/8/4
  Time: 20:43
  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>
    <form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
        <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>

3.配置文件上传bean#

<!--id一定要按是multipartResolver-->
<!--    文件上传配置-->
    <bean  class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
<!--        文件上传大小配置-->
        <property name="maxUploadSize" value="10487560"/>
<!--        在这里设置了文件放入临时文件夹的最小大小限制,那么这个属性到底还有什么作用呢?-->
<!--        查询得知:此为阈值,低于此值,则保存在内存中,如高于此值,则生成硬盘上的临时文件-->
        <property name="maxInMemorySize" value="40960"/>
    </bean>

4.文件上传#

package com.cb.Controller;


import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

@RestController()
public class FileUp {
		
    @PostMapping("/upload")
    //把前端上传的文件转化为CommonsMultipartFile对象 ,如果是多个文件就转换为CommonsMultipartFile数组
 
    public String up(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request){

        //获取文件真实名
        String filename = file.getOriginalFilename();

//        获取保存路径
        String realPath = request.getServletContext().getRealPath("/upload");
//        String realPath = "classpath:/upload";
        System.out.println(realPath);
        File pathfile = new File(realPath);
        if(!pathfile.exists()){
            pathfile.mkdir();
        }
        //保存文件
        try {
            file.transferTo(new File(realPath+"/"+filename));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "success : 成功";
    }
}

作者:Esofar

出处:https://www.cnblogs.com/firsthelloworld/p/13437625.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   我不想学编丿程  阅读(145)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示