SpringMvc进阶使用(适合快速复习)

Spring Mvc 进阶使用

一、 Spring Mvc的基础认识

MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。

1. mvc基础架构

2. mvc的实现原理

mvc的实现原理图
SpringMVC的具体执行流程:

​ 当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
在这里插入图片描述

二、开始使用Springmvc

2.1 环境的搭建

基本步骤:

  1. 创建maven项目,并勾选出快速创建web环境项目选项(webapp)
  2. 添加pom依赖
  3. 编写web.xml文件
  4. 编写SpringMvc相关xml配置文件(如果是SSM还需要编写spring的配置文件)
  5. 创建并编写Controller相关代码
  6. 配置tomcat(>7.0),并导入该项目

创建maven项目,并勾选出快速创建web环境项目选项(webapp)

2. 添加pom依赖
(此处应该有版本控制,不能想下面一样每个都写5.2.3… 像这样的版本号)

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
    </dependencies>

3. 编写web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联springmvc的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
    </servlet>
    <!--匹配servlet的请求,/标识匹配所有请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--/*和/都是拦截所有请求,/会拦截的请求不包含*.jsp,而/*的范围更大,还会拦截*.jsp这些请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4. 编写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">

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

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

    <bean id="/hello" class="com.mashibing.controller.HelloController"></bean>
</beans>

** 5. 创建并编写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 HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //创建模型和视图对象
        ModelAndView mv = new ModelAndView();
        //将需要的值传递到model中
        mv.addObject("msg","helloSpringMVC");
        //设置要跳转的视图,
        mv.setViewName("hello");
        return mv;
    }
}

6. 配置tomcat(>7.0),并导入该项目

2.2 核心注解

标注在类上的注解:

核心注解说明
@Controller-
@RestController-
@RequestMapping设置整个控制层的请求前缀
@SessionAttributes此注解可以表示,当向request作用域设置数据的时候同时也要向session中保存一份,此注解有两个参数,一个value(表示将哪些值设置到session中),另外一个type(表示按照类型来设置数据,一般不用,因为有可能会将很多数据都设置到session中,导致session异常)

标注在方法上的注解

核心注解说明
@RequestMapping指定 name属性,设置请求路径(根据method参数值,支持多种请求方式,默认都支持)
@ResponseBody设置返回的方式,返回JSON 字符串。如果没有这个注解的话,就放回对应的视图
@GetMapping指定 name属性,设置请求路径,但只支持 Get 请求
@PostMapping和上述基本一直,但只支持 Post 请求
@DeleteMapping和上述基本一直,但只支持 Delete 请求

注意: 默认是不支持,put、delete等请求的,这属于隐藏请求方式,需要自己手动开启(需要的话,自己可以百度自查,如何开启)

标注在参数上的注解

核心注解说明
@RequestParam指定请求的参数(一般通过请求url后的参数中获取,默认取相同名字的值)(建议指定相应的name)
@RequestBody获取请求体中的值,(前端返回JSON数据格式,然后再通过转换成指定的对象格式)
@PathVariable获取请求路径的值,默认取相同名字的值(建议指定相应的name)
@RequestHeader获取请求头信息
@CookieValue获取cookie中的值

注意: 参数上指定了这些注解,默认是必传的参数,当然也可以设置参数为非必传(required=false)

3. 乱码问题

说明:

我们在表单或者发送请求的时候,经常会遇到中文乱码的问题,那么如何解决乱码问题呢?
GET请求:在server.xml文件中,添加URIEncoding=“UTF-8”
POST请求:编写过滤器进行实现

解决方案:在web.xml配置文件中添加编码过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--
        关联springmvc的配置文件:
        此配置文件的属性可以不添加,但是需要在WEB-INF的目录下创建 前端控制器名称-servlet.xml文件
        -->

        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
    </servlet>
    <!--匹配servlet的请求,
    /:标识匹配所有请求,但是不会jsp页面
    /*:拦截所有请求,拦截jsp页面

     但是需要注意的是,当配置成index.html的时候,会发现请求不到
     原因在于,tomcat下也有一个web.xml文件,所有的项目下web.xml文件都需要继承此web.xml
     在服务器的web.xml文件中有一个DefaultServlet用来处理静态资源,但是url-pattern是/
     而我们在自己的配置文件中如果添加了url-pattern=/会覆盖父类中的url-pattern,此时在请求的时候
     DispatcherServlet会去controller中做匹配,找不到则直接报404
     而在服务器的web.xml文件中包含了一个JspServlet的处理,所以不过拦截jsp请求
    -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--解决post请求乱码-->
        <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>

</web-app>

2.4 对Servlet原生API的支持

HttpSessionHttpServletRequestHttpServletResponse 等一系列API
(如果想更加深入理解Servlet 原生API的使用,可以自己查询相关文章)

2.5 参数和页面的传递(ModelAndView

直接上案例

@Controller
public class OutputController {

    @RequestMapping("mv")
    public ModelAndView mv(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("output");	// 设置视图页面
        mv.addObject("msg","hello.modelAndView");	// 添加返回参数
        return mv;
    }
}

2.6 页面转发和重定向

此功能主要是由 视图解析器 完成的功能

使用案例:(forwardredirect

	/**
     * 当使用转发的时候可以添加前缀forward:index.jsp,此时是不会经过视图解析器的,所以要添加完整的名称
     * forward:也可以由一个请求跳转到另外一个请求
     */
    @RequestMapping("/forward01")
    public String forward(){
        System.out.println("1");
        return "forward:/index.jsp";
    }
    /**
     * redirect :重定向的路径
     *      相当于 response.sendRedirect("index.jsp")
     *      跟视图解析器无关
     */
    @RequestMapping("redirect")
    public String redirect(){
        System.out.println("redirect");
        return "redirect:/index.jsp";
    }

2.7 静态资源访问

当页面中包含静态资源的时候我们能够正确的获取到吗?

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    pageContext.setAttribute("ctx",request.getContextPath());
%>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello springmvc
<img src="${ctx}/images/timg.jpg">
</body>
</html>

springmvc.xml中添加相关配置

<!--
此配置表示  我们自己配置的请求由controller来处理,但是不能请求的处理交由tomcat来处理
静态资源可以访问,但是动态请求无法访问
-->
<mvc:default-servlet-handler/>
<!--保证静态资源和动态请求都能够访问-->
<mvc:annotation-driven/>

## 三、高级使用 ### 3.1 返回JSON数据

相关注解:@ResponseBody@RestController

3.2 获取请求体 - @RequestBody

注意:一个请求只能有一个请求体
请求的参数,都是放在请求体中的。
@RequestParam不同。

3.3 文件处理

springmvc默认是不添加文件组件的(九大组件)

springmvc.xml的配置中,应该添加上:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="defaultEncoding" value="UTF-8"></property>
    <property name="maxUploadSize" value="1024000"></property>
</bean>

文件上传:

@Controller
public class FileController {

    @RequestMapping("/download")
    public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception {
        //获取要下载文件的路径及输入流对象
        ServletContext servletContext = request.getServletContext();
        String realPath = servletContext.getRealPath("/script/jquery-1.9.1.min.js");
        FileInputStream fileInputStream = new FileInputStream(realPath);

        byte[] bytes = new byte[fileInputStream.available()];
        fileInputStream.read(bytes);
        fileInputStream.close();
        //将要下载文件内容返回
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Content-Disposition","attachment;filename=jquery-1.9.1.min.js");
        return  new ResponseEntity<byte[]>(bytes,httpHeaders,HttpStatus.OK);
    }
}

文件下载:

@Controller
public class FileController {
	@RequestMapping(value = "/testUpload", method = RequestMethod.POST)
	    public String testUpload(@RequestParam(value = "desc", required = false) String desc, 
	    @RequestParam("file") MultipartFile multipartFile) throws IOException {
	        System.out.println("desc : " + desc);
	        System.out.println("OriginalFilename : " + multipartFile.getOriginalFilename());
	        multipartFile.transferTo(new File("D:\\file\\"+multipartFile.getOriginalFilename()));
	
	        return "success"; //增加成功页面: /views/success.jsp
	    }
}

3.4 国际化操作

核心步骤:

  1. 实现接口 LocaleResolver
  2. springmvc.xml配置文件中,添加进入容器中

四、进阶使用

4.1. 自定义视图解析器 – ViewResolver

相关接口:视图解析器 ViewResolver 和 视图 View

使用案例

  1. 自定义视图:实现 View 接口
public class MyView implements View {

    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("保存的对象是:"+model);
        response.setContentType("text/html");
        response.getWriter().write("欢迎加入马士兵教育");
    }

    /**
     * 返回数据内容的类型
     * @return
     */
    public String getContentType() {
        return "text/html";
    }
}
  1. 自定义视图解析器:实现 ViewResolver 接口
public class MyViewResolver implements ViewResolver, Ordered {
    private int order = 0;
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        //如果前缀是msb:开头的就进行解析
        if (viewName.startsWith("msb:")){
            System.out.println("msb:");
            return new MyView();
        }else{
            //如果不是,则直接返回null
            return null;
        }
    }
    public int getOrder() {
        return this.order;
    }
    public void setOrder(Integer order) {
        this.order = order;
    }
}
  1. springmvc.xml配置文件中添加进自定义视图解析器

(在初始化视图解析器时,会根据对象类型获取Bean对象。因此只要将视图解析器,注入IOC容器中即可)

<?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: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/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.mashibing"></context:component-scan>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <bean class="com.mashibing.view.MyViewResolver">
        <property name="order" value="1"></property>
    </bean>
</beans>

4.2. 自定义类型转换器 – Converter

相关接口:

使用案例:

  1. 创建一个实体类:User.java
@Setter
@Getter
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
}
  1. 创建自定义转换器:MyConverter.java
@Component
public class MyConverter implements Converter<String, User> {
    public User convert(String source) {
        User user = null;
        String[] split = source.split("-");
        if (source!=null && split.length==4){
            user = new User();
            user.setId(Integer.parseInt(split[0]));
            user.setName(split[1]);
            user.setAge(Integer.parseInt(split[2]));
            user.setGender(split[3]);
        }
        return user;
    }
}
  1. springmvc.xml的配置文件中添加装换器
    (转换器不是mvc中的九大组件之一,不会从IOC容器中获取转换器)
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <ref bean="myConverter"></ref>
        </set>
    </property>
</bean>

适用场景:

4.3. 自定义日期格式装换器 – @DateTimeFormat

有时候我们经常需要在页面添加日期等相关信息,此时需要制定日期格式化转换器,此操作非常简单:只需要在单独的属性上添加@DateTimeFormat 注解即可,制定对应的格式

4.4. 数据校验

一般情况下我们会在前端页面实现数据的校验,但是大家需要注意的是前端校验会存在数据的不安全问题,因此一般情况下我们都会使用前端校验+后端校验的方式,这样的话既能够满足用户的体验度,同时也能保证数据的安全,下面来说一下在springmvc中如何进行后端数据校验。

JSR303是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 。JSR 303 (Java Specification Requests意思是Java 规范提案)通过 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证。

JSR303:
在这里插入图片描述
Hibernate Validator 扩展注解:
在这里插入图片描述

使用案例

  1. 导入pom相关依赖:
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.0.Final</version>
</dependency>
  1. 编写实体类:User.java
@Data
public class User {
    private Integer id;
    @NotNull
    @Length(min = 5,max = 10)
    private String name;
    private Integer age;
    private String gender;
    @Past
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birth;
    @Email
    private String email;
}
  1. 编写controller代码:DataValidateController.java
@Controller
public class DataValidateController {
    @RequestMapping("/dataValidate")
    public String validate(@Valid User user, BindingResult bindingResult) {
        System.out.println(user);
        if (bindingResult.hasErrors()) {
            System.out.println("验证失败");
            return "redirect:/index.jsp";
        } else {
            System.out.println("验证成功");
            return "hello";
        }
    }
}
  1. 编写页面:form.jsp
<%--
  Created by IntelliJ IDEA.
  User: root
  Date: 2020/3/12
  Time: 15:23
  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="dataValidate" method="post">
  编号:<input type="text" name="id"><br>
  姓名:<input type="text" name="name"><br>
  年龄:<input type="text" name="age"><br>
  性别:<input type="text" name="gender"><br>
  日期:<input type="text" name="birth"><br>
  邮箱:<input type="text" name="email"><br>
  <input type="submit" value="提交">
</form>
  </body>
</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值