Java研学-SpringMVC(一)

一 Spring Web介绍

1 MVC 思想

MVC思想

2 Spring MVC

SpringMVC

ServletWeb 服务的模块,包含对 MVCREST 的实现,Spring MVCWeb:提供与 Web 的集成,基于 Web 应用程序上下文。
WebSocket:实现客户端与服务端主动通信。
Portlet:提供了在 Portlet 环境中实现 MVC

  Spring MVC 是 Spring 对 MVC 思想的实现,它解决 Web 开发中常见的问题(参数接收、文件上传、表单验证、国际化等),而且使用简单,与 Spring 无缝集成。支持 RESTful 风格的 URL 请求 ,采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性,易与其他视图技术集成。

二 前端控制器

1 介绍

  前端控制器(Front Controller)是一种设计模式,常用于Web应用程序开发中。它主要负责集中处理所有的请求,并根据这些请求的类型和性质,将其分派给相应的处理程序或控制器。通过这种方式,前端控制器实现了应用程序的中心化管理和控制。做一个共同的处理,如权限检查,授权,日志记录等。因为前端控制的集中处理请求的能力,因此提高了可重用性和可拓展性。

前端控制器

2 Spring MVC 的前端控制器

  Spring MVC 提供了一个 DispatcherServlet 类作为前端控制器,使用 Spring MVC 必须在 web.xml 中配置前端控制器。处理请求的对象称之为处理器或后端控制器,Spring MVC 中称之为 Controller,如处理学生请求即 StudentController

三 简单Demo

1 Demo构建

在这里插入图片描述

2 导入依赖

<?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>cn.tj</groupId>
  <artifactId>spring-mvc</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <spring.version>5.0.8.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--所需依赖 统一管理 于properties中定义-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
          <uriEncoding>UTF-8</uriEncoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

3 配置前端控制器 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>
        <!--加载mvc配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <!--<load-on-startup>标签值为正整数时,表示容器在应用启动时就加载这个servlet-->
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!--设置请求拦截规则 拦截所有请求进入前端控制器-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4 创建处理器 HelloController

@Controller
@RequestMapping("hello")
public class HelloController {
    /*后台方法*/
    @RequestMapping("hello")
    public ModelAndView hello(){
        System.out.println("spring mvc 入门示例....");
        // 该对象有作用域和转发等功能(不是重定向)
        ModelAndView mav =new ModelAndView();
        // 跳转携带的参数 底层存入request的作用域
        mav.addObject("msg","hello spring mvc!");
        // 设置跳转的页面路径
        mav.setViewName("/WEB-INF/views/ok.jsp");
        // 跳转路径
        return mav;
    }
}

5 创建spring容器 spring-mvc.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:context="http://www.springframework.org/schema/context"
       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
       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
">
    <!--开启springmvc注解扫描-->
    <context:component-scan base-package="cn.tj.controller"></context:component-scan>
    <!--开启springmvc注解驱动(解析器)-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--配置注解解析器之后以下bean就自动注入到spring容器中-->
<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>-->
<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>-->
<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>-->
<!--    -->
</beans>

6 创建跳转页面 ok.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ok</title>
</head>
<body>
<h3>此处一个EL表达式</h3>
${msg}
</body>
</html>

四 前端控制器的映射路径

1 映射路径的配置

  • 配置如 .do、.htm 是最传统方式,可以访问静态文件(图片、 JS、 CSS 等),但不支持 RESTful 风格。
  • 配置成 /,可以支持流行的 RESTful 风格,但会导致静态文件(图片、 JS、 CSS 等)被拦截后不能访问。
  • 配置成 /*,是错误的方式,可以请求到 Controller 中,但跳转到调转到 JSP 时被拦截,不能渲染 JSP 视图,也会导致静资源访问不了。

2 访问静态资源和 JSP 被拦截

  Tomcat 容器处理静态资源是交由内置 DefaultServlet 来处理的(拦截路径是 /),处理 JSP 资源是交由内置的 JspServlet 处理的(拦截路径是*.jsp | .jspx)。
  启动项目时,先加载容器的 web.xml,而后加载项目中的 web.xml。当拦截路径在两者文件中配置的一样,后面会覆盖掉前者。
  所以前端控制器配置拦截路径是 / 的所有静态资源都会交由前端控制器处理,而拦截路径配置 /
,所有静态资源和 JSP 都会交由前端控制器处理。

3 静态资源访问

① 方式一 web.xml 中修改前端控制器的映射路径,但访问控制器里的处理方法时,请求路径须携带 .do。

<servlet-mapping>
	<servlet-name>dispatcherServlet</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

② 方式二 mvc.xml中进行配置,该配置会在 Spring MVC 上下文中创建存入一个 DefaultServletHttpRequestHandler 的 bean,它会对进入 DispatcherServlet 的请求进行筛查,若不是映射的请求,就将该请求交由容器默认的 Servlet 处理。

<mvc:default-servlet-handler/> 

五 处理响应

  编写控制器里面的处理方法接受请求做响应,找视图文件和往作用域中存入数据。要处理方法要做响应,一般处理方法返回的类型为 ModelAndView 和 String。响应 HTML 格式数据

1 返回 ModelAndView

① 编写处理方法

// 方法中返回 ModelAndView 对象,此对象中设置模型数据并指定视图。
@Controller
public class ResponseController {
	// 提供方法处理请求,localhost/resp
	@RequestMapping("/resp") 
	public ModelAndView resp() {
		// 通过类对象,让Spring MVC找对应视图文件, 向作用域或者往模型中存入数据
		ModelAndView mv = new ModelAndView();
		// 向作用域或者模型中存入数据
		mv.addObject("msg", "方法返回类型是 ModelAndView");
		// 找视图
		mv.setViewName("/WEB-INF/views/resp.jsp");
		return mv;
	}
//addObject(String key, Object value):设置共享数据的 key 和 value。
//addObject(Object value):设置共享数据的 value,key 为该 value 类型首字母小写。

② 编写 JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%--对应路径下新建 resp.jsp--%>
    <title>响应</title>
</head>
<body>
    ${msg}
</body>
</html>

2 返回 String

  String 类型共享数据,需要同Model 参数组合使用,用其往作用域或模型中存入数据

@Controller
public class ResponseController {
	// 提供方法处理请求,localhost/resp
	@RequestMapping("/resp")
	public String resp(Model model) {
		// 往作用域或者模型中存入数据	
		model.addAttribute("msg", "方法返回类型是 String"); 
		// 返回视图名 
		return "/WEB-INF/views/resp.jsp"; 
	}
}

3 消除视图前缀后缀

  视图位置固定且统一选用一种视图技术,故视图后缀名也是一样的,那么处理方法设置的视图路径代码随着项目增长,会有大量重复。Spring MVC 提供配置方法消除视图路径重复,需在 mvc.xml进行配置

<!-- 
	配置视图解析器,配置后 Spring MVC 找视图的路径为:前缀+文件名(视图名)+后缀=后台返回的跳转路径
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<!-- 视图前缀 -->
	<property name="prefix" value="/WEB-INF/views/"/>
	<!-- 视图后缀 -->
	<property name="suffix" value=".jsp"/>
</bean>

<!--
原方法中返回如下
return "/WEB-INF/views/ok.jsp";
配置后返回如下
return "ok";
-->

六 请求转发及 URL 重定向

1 请求转发和 URL 重定向对比

地址栏WEB-INF共享请求数据表达重复提交
请求转发不变可以访问共享
URL 重定向不可访问不共享

2 请求转发

  forward 前缀为请求转发,相当于 request.getRequestDispatcher().forward(request,response),转发后浏览器地址栏不变,共享之前请求中的数据。(默认转发,可以省略)

@Controller
public class ResponseController {
	@RequestMapping("/forward")
	public String forward() {
		return "forward:/WEB-INF/views/ok.jsp"; 
	}
}

3 URL 重定向

  redirect 前缀为重定向,相当于 response.sendRedirect(),重定向后浏览器地址栏变为重定向后的地址,不共享之前请求的数据。(重定向可访问WEB-INF目录下文件)

@Controller
public class ResponseController {
	@RequestMapping("/redirect") 
	public String redirect() {
		return "redirect:/static/demo.html"; 
	}
}

4 路径问题

  请求转发或者 URL 重定向时,路径有无 / 的区别

// 加 /,使用是绝对路径(推荐使用),从项目根路径(webapp)下找;
// 没加 /,使用是相对路径,相对于上一次访问上下文路径的上一级找。
/response/test ---> "redirect:/hello.html" ---> localhost:/hello.html
/response/test ---> "redirect:hello.html"  ---> localhost:/response/hello.html
  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒疯狂展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值