JAVAEE框架技术之4springMVC入门

简介: JAVAEE框架技术之4springMVC入门

springMVC

回顾MVC

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

Model : javaBean (1.处理业务逻辑,2. 封装数据)
View: 视图  jsp/html(展示数据)
controller:控制器 (1.接收请求,2.调用模型,3.转发视图)

是将业务逻辑、数据、显示进行分离的方式来组织代码。

MVC主要作用是降低了视图与业务逻辑间的耦合度。

MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在一些差异!

SpringMVC概述

Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。它可以通过一套注解,让一个简单的Java类成为控制器,而无须实现任何接口。

简单一句话:SpringMVC简化Servlet的开发!!

总结:

SpringMVC主要解决web层的代码,本质是Servlet

Spring MVC的特点

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

springmvc 整体架构

原理-流程-springmvc面试必问

1、用户发起请求到控制器 DispatcherServlet(前端控制器)
2、前端控制器去handlerMapper查找Handler对象
3、HandlerMapper返回HandlerExecutorChain 执行链(包含两部分内容:Handler ,拦截器集合)
4、前端控制器,通过HandlerAdapter 适配器执行 Handler对象
5、Handler处理具体的业务逻辑
6、Handler处理完业务逻辑之后,返回ModelAndView  其中的View是视图名称
7、将ModelAndView返回前端控制器
8、前端控制器,通过ModelAndView 中的视图名称。在视图解析器中查找视图
9、返回真正的View 视图对象
10、渲染视图
11、返回用户响应

springmvc入门

创建一个工程

创建的maven web工程

导入依赖

<!--springmvc依赖包,springmvc 只有这一个包-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.2.9.RELEASE</version>
</dependency>
<!--serlvet-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.0</version>
  <scope>provided</scope>
</dependency>
<!--日志-->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.6.4</version>
</dependency>
<!--测试-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

tomcat插件

<build>
  <plugins>
    <!--添加tomcat插件-->
    <plugin>
       <groupId>org.apache.tomcat.maven</groupId>
       <artifactId>tomcat7-maven-plugin</artifactId>
       <version>2.2</version>
       <configuration>
           <port>8080</port>
           <path>/</path>
       </configuration>
    </plugin>
  </plugins>
</build>

dispatcherServlet控制器

配置web.xml中的添加dispatcherServlet

<!--前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加载指定配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--指定servlet在tomcat启动时创建-->
        <load-on-startup>1</load-on-startup>
    </servlet>    
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--
            springmvc基于拦截器实现; 拦截所有的controller请求,都会进入controller类中
       /  拦截所有controller请求, 包括 webapp下的静态资源如:html,js,css,img (不包括jsp)
            /* 拦截所有controller请求,包括 webapp下的静态资源如: jsp(包括jsp) html,js,css,img ..
            *.xx 
       *.do 匹配后缀
        -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

springmvc核心配置文件

  • springmvc-servlet.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>

自定义Handler(Controller)

public class Hello implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","这是第一个springmvc程序!!");
        //设置视图名   hello仅仅是视图的名字
        mv.setViewName("hello");
        return mv;
    }
}

配置HandlerMapping&HandlerAdapter -了解

<!--HandlerMapping  springmvc会自己配置无需配置  -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--HandlerAdapter  springmvc会自己配置无需配置-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

配置handler

<!--配置自定义的Handler,controller-->
    <bean name="/hello.do" class="cn.yanqi.controller.Hello"/>

配置视图解析器

通过源码分析,可以看是放在WEB-INF下

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

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
        ${msg}
</body>
</html>

测试

请求过程分析

注解开发

入门案例中的思考:
    1、每个类需实现Controller,麻烦
    2、每个类只能处理一个业务逻辑,不能是controller处理多个业务逻辑。
    3、每一个Controller都需要进行配置
    使用注解:解决上述问题

创建controller类

package cn.yanqi.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
 * @Auther: yanqi
 */
@Controller //表示当前是一个controller类
@RequestMapping("hello2")
public class Hello2 {
    // @RequestMapping(value="/show1.do")
    // @RequestMapping("show1.do")
    // @RequestMapping("/show1")
    @RequestMapping("show1")
    public ModelAndView test1(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","这是第一个springmvc注解!!");
        //设置视图名   hello仅仅是视图的名字
        mv.setViewName("hello");
        return mv;
    }
    @RequestMapping("show2")
    public ModelAndView test2(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","这是第一个springmvc注解!!");
        //设置视图名   hello仅仅是视图的名字
        mv.setViewName("hello");
        return mv;
    }
}

配置注解扫描器

<!--配置注解扫描包
扫描含有@Controller的类
-->
<context:component-scan base-package="cn.yanqi"/>
<!--开启注解驱动-->
<mvc:annotation-driven/>

测试


五种映射

1、标准URL映射 
2、Ant风格的URL映射*  **
3、占位符映射  
    @requestMapping (show/{userid}/{name} )  方法中(@pathVariable(“ userid”) String id)          http://localhost/hello2/833/yanqi.do 
4、限制请求方式映射 
    @requestMapping ( value=“ show2” , method=requestMehtod.POST)    错误405
    @GetMapping
      @PostMapping
5、限制请求参数映射  
    @requestMapping( value=”show3” , params=”abc”) 方法中(@requestParam(“abc”) String abc)

标准映射

/**
     * 标准映射
     * @return
     */
  @RequestMapping(value = "/show1.do")
    public ModelAndView test1(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","这是第一个springmvc注解!!");
        //设置视图名   hello仅仅是视图的名字
        mv.setViewName("hello");
        return mv;
    }

Ant风格的URL映射

单级目录匹配
    @RequestMapping("test/*/show") 
    访问:   /test/a/show.do  
    访问:   /test/abc/show.do
单级目录匹配:
    @RequestMapping("test/**/show") 
    访问:   hello/test/a/b/c/show.do
//http://localhost:8080/hello2/test/a/b/c/show4.do
    //http://localhost:8080/hello2/test/a/show4.do  多级目录可以写单级目录
    @RequestMapping("/test/**/show4")
    public ModelAndView test4(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","我是多级目录");
        mv.setViewName("hello");
        return mv;
    }
    //http://localhost:8080/hello2/test/a/show4.do
    @RequestMapping("/test/*/show5")
    public ModelAndView test5(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","我是单级目录");
        mv.setViewName("hello");
        return mv;
    }

占位符映射

@RequestMapping(“/user/{userId}/query")

通过*@PathVariable(“xxx”)* 获取请求路径中参数值

/**
     * 占位符
     * @param itemId
     * @param name
     * @return
     */
@RequestMapping("/show6/{itemId}/{name}")
public ModelAndView test6(@PathVariable("itemId") String itemId ,@PathVariable("name") String name){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","占位符:"+itemId +" : "+name);
        mv.setViewName("hello");
        return mv;
    }

限制请求方式映射

RequestMethod.POST @PostMapping(“xx”)

RequestMethod.GET @GetMapping(“xx”)

405 请求方式不合法

//get post 两种请求方式
  @RequestMapping(value = "/show9",method = {RequestMethod.POST,RequestMethod.GET})
    public ModelAndView test9(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求方式为 GET ,  POST");
        mv.setViewName("hello");
        return mv;
    }
  //post 请求方式
    @RequestMapping(value = "/show8",method = RequestMethod.POST)
    public ModelAndView test8(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求方式为 POST ");
        mv.setViewName("hello");
        return mv;
    }
  //get  请求方式
    @RequestMapping(value = "/show7",method = RequestMethod.GET)
    public ModelAndView test7(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求方式为 GET ");
        mv.setViewName("hello");
        return mv;
    }
//post 请求方式
    @PostMapping("show11")
    public ModelAndView test11(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求方式为 POST");
        mv.setViewName("hello");
        return mv;
    }
  //get 请求方式
    @GetMapping("show10")
    public ModelAndView test10(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求方式为 GET");
        mv.setViewName("hello");
        return mv;
    }
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/hello2/show11.do" method="post">
        <input type="submit">
    </form>
</body>
</html>

接口测试工具 : postmain

限定请求参数

可以防止用户把不必要的信息注入进来

400 请求参数不合法

@GetMapping(value = "show15",params = "id")          必须包含id
  @GetMapping(value = "show15",params = "!id")         不能包含id
  @GetMapping(value = "show15",params = "id!=1007")    包含id其值不为1007
  • 代码演示
//请求参数必须包含id  方式一
    @GetMapping(value = "show15",params = "id")
    public ModelAndView test15(@RequestParam("id") int id){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求参数:"+id);
        mv.setViewName("hello");
        return mv;
    }    
    //请求参数必须包含id   方式二
    @GetMapping("show12")
    public ModelAndView test12(@RequestParam("id") int id){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求参数:"+id);
        mv.setViewName("hello");
        return mv;
    }    
    //请求参数不参包含id
    @GetMapping(value ="show14",params = "!id")
    public ModelAndView test14(@RequestParam("name") String name){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求参数:"+name);
        mv.setViewName("hello");
        return mv;
    }
     //请求参数包含id其值不能为1007
    @GetMapping(value ="show13",params = "id!=1007")
    public ModelAndView test13(@RequestParam("id") int id){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","限定请求参数:"+id);
        mv.setViewName("hello");
        return mv;
    }

SpringMVC页面跳转

转发

返回字符串

@Controller
@RequestMapping("test")
public class TestController {
    //第一种 ModelAndView 转发到视图解析器
    @RequestMapping("show")
    public ModelAndView show(){
        return new ModelAndView("hello");
    }
    //第二种 String 转发到视图解析器
    @RequestMapping("show2")
    public String show2(){
        return "hello";
    }
    //第三种 void 没有返回的视图
    @RequestMapping("show3")
    @ResponseStatus(HttpStatus.OK)
    public void show3(){
        System.out.println("我没有要返回的结果。。。");
    }
    //第四种 转发--通过servlet内置对象
    @RequestMapping("show4")
    @ResponseStatus(HttpStatus.OK)
    public void show5(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //转发 -- 视图解析器
        request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response);
    }
}

forward关键字

以上我们用string类型,只能转发到视图解析器下, webapp下就无法转发,forward就可以解决

//第一种 转发--webapp   页面  
@RequestMapping("show3")
public String show3(){
  return "forward:/user.html"; //转发到webapp下的user.html
}
//第二种 转发--webapp   controller类
@RequestMapping("show4")
public String show4(){
  return "forward:/userController/getUser.do";//转发到controller中
}
//第三种 转发--ModelAndView
@RequestMapping("show5")
public ModelAndView show5(ModelAndView mv)  {
    mv.setViewName("forward:/user.html");//webapp下
    return mv;
}
//第四种 转发--通过servlet内置对象
@RequestMapping("show6")
@ResponseStatus(HttpStatus.OK)
public void show5(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //转发 -- webapp下
    request.getRequestDispatcher("/user.html").forward(request,response);
}

重定向

redirect关键字

此关键字的底层:response.sendRedirect(“web项目地址+重定向地址”);

@Controller
@RequestMapping("test")
public class TestController {
    //第一种 重定向 ModelAndView 
    @RequestMapping("show5")
    public ModelAndView show5(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("redirect:/user.html");//重定向webapp下的具体页面
        // mv.setViewName("redirect:/UserController/show1.do");//重定向具体的controller
        return mv;
    }
    //第二种 重定向 redirect关键字
    @RequestMapping("show6")
    public String show6(){
        return "redirect:/user.html";
        // return "redirect:/UserController/show1.do";
    }
    //第三种 重定向 绑定servlet内置对象
    @RequestMapping("show7")
    public void show7(HttpServletRequest request ,HttpServletResponse response) throws IOException {
        response.sendRedirect(request.getContextPath()+"/user.html");
        // response.sendRedirect(request.getContextPath()+"/UserController/show1.do");
    }
}    

SpringMVC存储数据

servlet存数据

@RequestMapping("/requestAPI")
public void requestAPI(HttpServletRequest request, HttpServletResponse response) throws Exception {
    request.setAttribute("name", "江一燕");
    request.getRequestDispatcher("/list.jsp").forward(request, response);
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    list页面
    ${name}
</body>
</html>

Model存数据

ModelAndView 存数据

Model 存数据

ModelMap 存数据

Map 存数据

以上都存在放request域中

//方式一 ModelAndView存数据
    @RequestMapping("TestModelAndView")
    public ModelAndView modelAndView(ModelAndView mv)  {
        mv.addObject("name", "小面包"); // 设置数据
        mv.setViewName("list");// 设置视图
        return mv;
    }
    //方式二 Model
    @RequestMapping("TestModel")
    public String modelAndView(Model model)  {
        model.addAttribute("email","yanqi@126.com");
        return "forward:/list.jsp";
    }
    //方式三 ModelMap
    @RequestMapping("TestModelMap")
    public String modelAndView(ModelMap modelMap)  {
        modelMap.addAttribute("city","beijing");
        return "forward:/list.jsp";
    }
    //方式四 Map
    @RequestMapping("TestMap")
    public String modelAndView(Map<Object,Object> map)  {
        map.put("age",28);
        return "forward:/list.jsp";
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>我是list页面</h3>
    ${requestScope.name}
    ${requestScope.email}
    ${requestScope.city}
    ${requestScope.age}
</body>
</html>

url-pattern

关于SpringMVC的\解读

一、\的作用

二、\配置详解

(1) .do
(2) /
(3) /

三、静态资源访问

方法一:使用

方法二:使用

目录显示问题无法处理

关于SpringMVC的解读

一、的作用

首先我们要知道配置的作用:将请求当作一个controller处理,然后dispatcherServlet(中央调度器)去调用HandleMapping(处理器映射器)查找到相应的处理器。

简单的来说就是匹配到的请求会去寻找controller

二、配置详解

(1) *.do

*.do会匹配这种格式的请求(请求地址),然后去查看controller中是否有这样的的controller。

(2) /

匹配根目录下的所有请求,包括静态资源的获取请求,例如:.css,.js,.html等静态资源,但是不会匹配到.jsp这样的后缀的url。

也就是说这些.html的请求都会被当作一个controller去请求,这样肯定是访问不到的,会报错404。

但是不会匹配到.jsp这样的后缀的url,也就是说.jsp就不会被经过dispatcherServelt,可以直接被访问,因此我们配置为\的时候就会访问.jsp是不会报错的,能被访问到。

(3) /*

匹配根目录下的所有请求,包括静态资源的获取请求,例如:.css,.js,.html等静态资源,包括.jsp这样的后缀的url。

也就是说这些,无论什么请求都会被当作一个controller来处理,所以我们在访问这些静态资源的时候都会报404错误。

三、静态资源访问

我们写成上面的/或者/*,就不能访问静态资源了,但是这样是不行的。所以我们再经过一些配置就可以访问静态资源了。

方法一:使用mvc:default-servlet-handler/

声明了后 springmvc 框 架 会 在 容 器 中 创 建DefaultServletHttpRequestHandler 处理器对象。它会像一个检查员,对进入 DispatcherServlet 的 URL 进行筛查,如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的 Servlet 处理。一般的服务器都有默认的 Servlet。

在 Tomcat 中,有一个专门用于处理静态资源访问的 Servlet 名叫 DefaultServlet。其为 default。可以处理各种静态资源访问请求。该 Servlet 注册在 Tomcat 服务 器的 web.xml 中。在 Tomcat 安装目录/conf/web.xml。

记得

声明注解驱动:mvc:annotation-driven />

方法二:使用mvc:resources/

声明格式:

location:标识静态资源所在目录。目录不要使用/WEB-INF/及其子目录。

mapping:标识对该资源的请求,全部资源注意是两个*号。

例:

记得

声明注解驱动:mvc:annotation-driven />

当作一个controller来处理,所以我们在访问这些静态资源的时候都会报404错误。

三、静态资源访问

我们写成上面的/或者/*,就不能访问静态资源了,但是这样是不行的。所以我们再经过一些配置就可以访问静态资源了。

方法一:使用mvc:default-servlet-handler/

声明了后 springmvc 框 架 会 在 容 器 中 创 建DefaultServletHttpRequestHandler 处理器对象。它会像一个检查员,对进入 DispatcherServlet 的 URL 进行筛查,如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的 Servlet 处理。一般的服务器都有默认的 Servlet。

在 Tomcat 中,有一个专门用于处理静态资源访问的 Servlet 名叫 DefaultServlet。其为 default。可以处理各种静态资源访问请求。该 Servlet 注册在 Tomcat 服务 器的 web.xml 中。在 Tomcat 安装目录/conf/web.xml。

记得

声明注解驱动:mvc:annotation-driven />

方法二:使用mvc:resources/

声明格式:

location:标识静态资源所在目录。目录不要使用/WEB-INF/及其子目录。

mapping:标识对该资源的请求,全部资源注意是两个*号。

例:

记得

声明注解驱动:mvc:annotation-driven />

目录
相关文章
|
3月前
|
Java 数据库连接 Maven
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
|
3月前
|
Java 数据库 数据安全/隐私保护
基于SSM框架实现管科类考研自我管理系统(分前后台spring+springmvc+mybatis+maven+jsp+jquery)
基于SSM框架实现管科类考研自我管理系统(分前后台spring+springmvc+mybatis+maven+jsp+jquery)
|
3月前
|
前端开发 Java Apache
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
69 0
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
|
18天前
|
前端开发 JavaScript Java
MVC框架:SpringMVC(三)
MVC框架:SpringMVC
30 0
|
18天前
|
JSON 前端开发 JavaScript
MVC框架:SpringMVC(二)
MVC框架:SpringMVC
35 0
|
18天前
|
前端开发 Java 应用服务中间件
MVC框架:SpringMVC(一)
MVC框架:SpringMVC
58 0
|
2月前
|
JSON 前端开发 Java
【JavaEE进阶】 关于Spring mvc 响应
【JavaEE进阶】 关于Spring mvc 响应
|
2月前
|
前端开发 Java 数据库连接
认识Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty
Spring框架 Spring是一个轻量级的开源框架,用于构建企业级应用。它提供了广泛的功能,包括依赖注入、面向切面编程、事务管理、消息传递等。Spring的核心思想是控制反转(IoC)和面向切面编程(AOP)。
71 3
|
3月前
|
JSON 前端开发 JavaScript
JAVAEE框架技术之5-springMVC参数绑定和异步交互
JAVAEE框架技术之5-springMVC参数绑定和异步交互
56 0
JAVAEE框架技术之5-springMVC参数绑定和异步交互
|
4月前
|
设计模式 前端开发 JavaScript
Spring MVC(一)【什么是Spring MVC】
Spring MVC(一)【什么是Spring MVC】