【Java学习总结】SpringMVC

一、概述

1.MVC

  • MVC开始是存在于桌面程序中的,M是指业务模型(Model),V是指用户界面(View),C则是控制器(Controller)。
  • MVC是一种框架模式。
  • MVC是将业务逻辑、数据、显示分离的方法来组织代码,降低了视图与业务逻辑间的双向偶合。

在这里插入图片描述
职责分析:
Controller:控制器

  • 取得表单数据
  • 调用业务逻辑
  • 转向指定的页面

Model:模型

  • 业务逻辑
  • 保存数据的状态

View:视图

  • 显示页面

2.SpringMVC概述

Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
SpringMVC的优点:

  • 轻量级框架
  • 功能强大
  • 高效,基于请求响应的MVC框架
  • 与Spring无缝结合

二、第一个SpringMVC程序(HelloSpringMVC)

1.配置文件实现

(1)创建一个Maven项目并导入依赖。同时添加web支持。
(2)配置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:这个是SpringMVC的核心;请求分发器,前端控制器-->
    <servlet>
        <servlet-name>SpringMVC</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>
        <!--启动顺序,数字越小,启动越早-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

(3)配置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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

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

    <!--视图解析器-->
    <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)编写Controller接口的实现类

public class HelloController implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        ModelAndView modelAndView = new ModelAndView();
        //业务代码
        String result = "HelloSpringMVC";
        modelAndView.addObject("msg",result);
        //视图跳转
        modelAndView.setViewName("test");
        return modelAndView;
    }
}

(5)将Controller实现了配置到SpringIoC容器中

<!--Handler-->
<bean id="/hello" class="com.example.controller.HelloController"/>

(6)编写要跳转到的test.jsp文件

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

2.注解实现

(1)创建一个Maven项目并导入依赖。同时添加web支持。
(2)配置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">
    <!--1.注册Servlet-->
    <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:SpringMVC-Servlet.xml</param-value>
        </init-param>
        <!--启动顺序,数字越小,启动越早-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--所有的请求都会被SpringMVC拦截-->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

(3)配置SpringMVC的配置文件SpringMVC-Servlet.xml

扫描二维码关注公众号,回复: 16014959 查看本文章
<?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"
       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/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.example.controller"/>
    <!-- 让Spring MVC不处理静态资源 -->
    <mvc:default-servlet-handler />
    <!--
    支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
     -->
    <mvc:annotation-driven />

    <!-- 视图解析器 -->
    <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)编写Controller层

@Controller
@RequestMapping("/hello")
public class HelloController {
    
    
    // localhost:8080/hello/h1
    @RequestMapping("/h1")
    public String hello(Model model){
    
    
        //封装数据
        model.addAttribute("msg","HelloSpringMVCAnnotation");
        return "test";//会被视图解析器处理
    }
}
  • @Controller是为了让Spring IOC容器初始化时自动扫描到;
  • @RequestMapping是为了映射请求路径,这里因为类与方法上都有映射所以访问时应该是/HelloController/hello;
  • 方法中声明Model类型的参数是为了把Action中的数据带到视图中;
  • 方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/test.jsp

(5)编写view层test.jsp
在WEB-INF/ jsp目录中创建test.jsp ,视图可以直接取出并展示从Controller带回的信息。

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

三、控制器Controller详解

控制器负责解析用户的请求并将其转换为一个模型。控制器提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。

1.通过接口定义Controller

在此方法中,可以通过实现Controller接口,并重写其中的handleRequest方法实现。
测试步骤如下:
(1)编写Controller的实现类并重写handleRequest方法。

//只要实现了Controller的类,说明这就是一个控制器了
public class ControllerTest1 implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","ControllerTest1");
        modelAndView.setViewName("test");
        return modelAndView;
    }
}

(2)Spring配置文件中注册请求的bean;
name对应请求路径,class对应处理请求的类

<bean id="/t1" class="com.example.controller.ControllerTest1"/>

(3)在WEB-INF/jsp目录下编写前端test.jsp。

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

2.通过注解实现定义Controller

@Controller注解类型用于声明Spring类的实例是一个控制器。
(1)使用注解前,现在SpringMVC配置文件中配置扫描包。

    <!--自动扫描指定的包,下面所有注释类交给IOC容器处理-->
    <context:component-scan base-package="com.carry.controller"/>

(2)用注解实现Controller。

@Controller
@RequestMapping("/c2")
public class ControllerTest2 {
    
    
    @RequestMapping("/t1")
    public String test1(Model model){
    
    
        model.addAttribute("msg","ControllerTest3");
        return "test";
    }
}

注意:访问路径为http://localhost:8080/项目名/c1/t1 , 需要先指定类的路径再指定方法的路径;

3.跳转方式

(1)通过ModelAndView对象

通过ModelAndView对象实现跳转,需要搭配视图解析器使用。
页面 : {视图解析器前缀} + viewName +{视图解析器后缀}。

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

对应的controller类

    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","ControllerTest1");
        modelAndView.setViewName("test");
        return modelAndView;
    }

(2)通过SpringMVC实现

@Controller
public class ModelTest1 {
    
    
    @RequestMapping("/m1/t1")
    public String test1(Model model){
    
    
        //重定向
        model.addAttribute("msg","ModelTest1");
        return "redirect:/index.jsp";
    }
    
    @RequestMapping("/m1/t2")
    public String test1(Model model){
    
    
        //转发
        model.addAttribute("msg","ModelTest1");
        return "forward:/index.jsp";
    }
}

4.乱码问题

以前乱码问题通过过滤器解决 , 而SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置 。
在web.xml中进行如下配置即可。

    <!--配置SpringMVC的乱码过滤-->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

四、拦截器

1.什么是拦截器

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
过滤器与拦截器区别:

  • 过滤器是Servlet规范的一部分,任何JavaWeb工程都能使用;拦截器是SpringMVC的,只有使用了SpringMVC框架的工程才能使用。
  • 过滤器在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截;拦截器只会拦截访问的控制器方法, 如果访问的是jsp /html /css /image /js是不会进行拦截的。

2.自定义拦截器

自定义拦截器需要实现 HandlerInterceptor 接口。
(1)编写 HandlerInterceptor 接口的实现类。

public class MyInterceptor implements HandlerInterceptor {
    
    
    //return true; 执行下一个拦截器,放行
    //return false; 不执行下一个拦截器
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("=========处理前=========");
        return true;
    }
    //日志
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("=========处理后=========");
    }
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("=========清理=========");
    }
}

(2)在springmvc的配置文件中配置拦截器

    <!--拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- /** 包括这个请求下面的所有的请求-->
            <mvc:mapping path="/**"/>
            <bean class="com.carry.config.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

(3)编写一个Controller

@Controller
public class InterceptorController {
    
    
	@RequestMapping("/interceptor")
	@ResponseBody
	public String testFunction() {
    
    
		System.out.println("控制器中的方法执行了");
		return "hello";
	}
}

(4)前端 index.jsp

<a href="${pageContext.request.contextPath}/interceptor">拦截器测试</a>

猜你喜欢

转载自blog.csdn.net/qq_43647936/article/details/121595703