SpringMVC

SpringMVC 概述

  • 三层架构:

    • 表现层:负责数据展示
    • 业务层:负责业务处理
    • 数据层:负责数据操作
  • MVC(Model View Controller),一种用于设计创建Web应用程序表现层的模式。

    • Model(模型):数据模型,用于封装数据。
    • View(视图):页面视图,用于展示数据。
      • jsp
      • html
    • Controller(控制器):
      • 将数据和页面按照一定的关系组合在一起。
      • 处理用户交互的调度器,用于根据用户需求处理程序逻辑。
      • Servlet
      • SpringMVC

SpringMVC是一种基于Java实现MVC模型的轻量级Web框架

SpringMVC优点:

  • 使用简单
  • 性能突出
  • 灵活性强

入门案例

导入jar包

<!-- servlet3.1规范的坐标 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<!--jsp坐标-->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.9.RELEASE</version>
</dependency>
<!--spring web的坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.1.9.RELEASE</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.9.RELEASE</version>
</dependency>

SpringMVC配置文件

<?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">

    <!--开启mvc的注解驱动-->
    <mvc:annotation-driven/>

    <context:component-scan base-package="com.itheima.controller">
    	<!--通过注解过滤,只扫描包含@Controller注解修饰的bean-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--释放静态资源-->
    <mvc:default-servlet-handler/>

    <!-- 配置视图解析器,进行页面的跳转 -->
    <!-- 前端控制器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--跳转的页面的前缀名称-->
        <property name="prefix" value=""/>
        <!--跳转的页面的后缀名称-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

web.xml中配置SpringMVC核心控制器,用于将请求转发到对应的具体业务处理器Controller中

<!--SpringMVC的核心控制器-->
<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    	<!--加载SpringMVC配置文件-->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-mvc.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

设置编码过滤器

<!-- 编码过滤器 -->
<filter>
    <filter-name>encodingFilter</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>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

如果前端页面是HTML页面,需要加上以下配置

<!--修改默认访问HTML页面-->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>

设置前端返回页面

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

@Controller("userServlet")
public class UserServlet {

    //设定当前方法的访问映射地址
    @RequestMapping("/save")
    public String save() {
        System.out.println("UserServlet save方法执行了");
        //返回访问页面
        return "success";
    }
}

这里返回页面时候,只是返回了一个“success”字符串,是因为在SpringMVC配置文件中,配置了视图解析器。

流程分析

  • 服务器启动
    1、加载web.xml中DispatcherServlet
    2、读取spring-mvc.xml中的配置,加载所有com.itheima包中所有标记为bean的类
    3、读取bean中方法上方标注@RequestMapping的内容
  • 处理请求
    1、DispatcherServlet配置拦截所有请求 /
    2、使用请求路径与所有加载的@RequestMapping的内容进行比对
    3、执行对应的方法
    4、根据方法的返回值在webapp目录中查找对应的页面并展示

SpringMVC 技术架构图

在这里插入图片描述

  • DispatcherServlet:前端控制器,是整体流程控制的中心,由其调用其它组件处理用户的请求,有效的降低了组件间的耦合性。
  • HandlerMapping:处理器映射器, 负责根据用户请求找到对应具体的Handler处理器。
  • Handler:处理器,业务处理的核心类,通常由开发者编写,描述具体的业务。
  • HandlAdapter:处理器适配器,通过它对处理器进行执行。
  • View Resolver:视图解析器, 将处理结果生成View视图。
  • View:视图,最终产出结果, 常用视图如jsp、html。
    在这里插入图片描述
SpringMVC配置文件
<?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">

    <!--开启注解扫描-->
    <mvc:annotation-driven/>

    <!--扫描包-->
    <context:component-scan base-package="com.itheima.controller">
		<!--通过注解过滤,只扫描包含@Controller注解修饰的bean-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--释放静态资源-->
    <mvc:default-servlet-handler/>

    <!-- 配置视图解析器,进行页面的跳转 -->
    <!-- 前端控制器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--跳转的页面的前缀名称-->
        <property name="prefix" value=""/>
        <!--跳转的页面的后缀名称-->
        <property name="suffix" value=".jsp"/>
    </bean>
	
	<!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--拦截的路径-->
            <mvc:mapping path="/handleRun"/>
            <!--指定具体的拦截器类-->
            <bean class="com.itheima.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

    <!--文件上传-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--上传文件的编码类型-->
        <property name="defaultEncoding" value="UTF-8"/>
        <!--文件上传的总大小(10M)-->
        <property name="maxUploadSize" value="10485600"/>
        <!--单个文件的大小(5M)-->
        <property name="maxUploadSizePerFile" value="5242800"/>
    </bean>
	
	<!--配置异常处理器-->
    <bean id="exceptionResolver" class="com.itheima.exception.ExceptionAdvice"/>
</beans>
中文乱码处理
<!--乱码处理过滤器,与Servlet中使用的完全相同,差异之处在于处理器的类由Spring提供-->
<filter>
    <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
日期类型格式转换-全局配置
<!--1.设定格式类型Converter,注册为Bean,受SpringMVC管理-->
<bean id="conversionService"
      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!--2.自定义Converter格式类型设定,该设定使用的是同类型覆盖的思想-->
    <property name="formatters">
        <!--3.使用set保障相同类型的转换器仅保留一个,避免冲突-->
        <set>
            <!--4.设置具体的格式类型-->
            <bean class="org.springframework.format.datetime.DateFormatter">
                <!--5.类型规则-->
                <property name="pattern" value="yyyy-MM-dd"/>
            </bean>
        </set>
    </property>
</bean>

<!--6.启用自定义Converter-->
<mvc:annotation-driven conversion-service="conversionService"/>

请求Request

普通类型参数传递
@Controller
public class UserController {

	@RequestMapping("/save")
	public String save() {
	    System.out.println("save 方法执行了...");
	    return "success";
	}

	//http://localhost:8080/mvc/save?name=zhangsan
	@RequestMapping("/save2")
	public String save2(String name) {
	    System.out.println(name);
	    return "success";
	}

	/**
	 * required = true,必须传参数
	 * @RequestParam 绑定请求参数与对应处理方法形参间的关系
	 * required = true 必须传参
	 */
	@RequestMapping("/save3")
	public String save3(@RequestParam(name = "username", required = true) String name, Integer age) {
	    System.out.println(name + "," + age);
	    return "success";
	}
}

@RequestParam:绑定请求参数与对应处理方法形参间的关系
required = true:必须传参

对象类型参数
@Controller
public class UserController {

	@RequestMapping("/save1")
    public String save1(User user) {
        System.out.println(user);
        return "success";
    }
}

当我们传入的参数有日期格式的时候。SpringMVC底层默认的日期格式是yyyy/MM/dd,我们可以通过配置文件,将日期格式转换为yyyy-MM-dd。

<!--1.设定格式类型Converter,注册为Bean,受SpringMVC管理-->
<bean id="conversionService"
      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!--2.自定义Converter格式类型设定,该设定使用的是同类型覆盖的思想-->
    <property name="formatters">
        <!--3.使用set保障相同类型的转换器仅保留一个,避免冲突-->
        <set>
            <!--4.设置具体的格式类型-->
            <bean class="org.springframework.format.datetime.DateFormatter">
                <!--5.类型规则-->
                <property name="pattern" value="yyyy-MM-dd"/>
            </bean>
        </set>
    </property>
</bean>

<!--6.启用自定义Converter-->
<mvc:annotation-driven conversion-service="conversionService"/>

也可以采用注解的方式进行日期格式转换,还需要在对象的日期属性上加上注解

@RequestMapping("/save")
public ModelAndView save(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
	System.out.println(date);
	return mav;
}

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;
请求映射

不仅可以加在方法上,还可以加在类上。

在这里,如果同时加在类上和方法上,我们可以理解为,类上的为一级访问路径,方法上的为二级访问路径。

当在方法上加上了访问路径,我们在返回页面的时候,要将返回的页面放在访问路径的目录下。

@RequestMapping("/save")

响应Response

响应页面(跳转页面)

转发(默认):可以访问WEB-INF下的页面

@Controller
@RequestMapping("/user")
public class UserController2 {

    @RequestMapping("/save")
    public String save(User user){
        System.out.println(user);
        // return "success";
        return "forward:success";
    }
}

重定向:不能够访问WEB-INF下的页面

@Controller
@RequestMapping("/user")
public class UserController2 {

    @RequestMapping("/save")
    public String save(User user){
        System.out.println(user);
        return "redirect:success";
    }
}
<!-- 配置视图解析器,进行页面的跳转 -->
<!-- 前端控制器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--跳转的页面的前缀名称-->
    <property name="prefix" value="/WEB-INF/"/>
    <!--跳转的页面的后缀名称-->
    <property name="suffix" value=".jsp"/>
</bean>

配置文件中对页面访问的配置

在配置文件中对访问页面进行配置后,在访问页面时,不需要加上forward 。

@RequestMapping("/save")
public void save(User user){
    System.out.println(user);
}

当方法返回值为void的时候,访问路径就是返回页面的页面名字。

带数据页面跳转
@Controller
public class BookController {

    //使用原生request对象传递参数
    @RequestMapping("/save")
    public String save(HttpServletRequest request) {
        request.setAttribute("name", "zhangsan");
        return "page";
    }

    //使用Model形参传递参数
    @RequestMapping("/save2")
    public String save2(Model model) {
        //添加数据的方式,key对value
        model.addAttribute("name", "李四");
        //引用类型
        User user = new User();
        user.setName("张三");
        //添加数据的方式,key对value
        model.addAttribute("user", user);
        //返回页面
        return "page";
    }

    //使用ModelAndView形参传递参数,该对象还封装了页面信息
    @RequestMapping("/save3")
    public ModelAndView save3(ModelAndView modelAndView) {
        User user = new User();
        user.setName("王五");
        //添加数据的方式,key对value
        modelAndView.addObject("user", user);
        //添加数据的方式,key对value
        modelAndView.addObject("name", "赵六");
        //设置页面的方式,该方法最后一次执行的结果生效
        modelAndView.setViewName("page");
        //返回值设定成ModelAndView对象
        return modelAndView;
    }

    //ModelAndView对象支持转发的手工设定,该设定不会启用前缀后缀的页面拼接格式
    @RequestMapping("/save4")
    public ModelAndView save4(ModelAndView modelAndView) {
        modelAndView.setViewName("forward:/WEB-INF/page/page.jsp");
        return modelAndView;
    }

    //ModelAndView对象支持重定向的手工设定,该设定不会启用前缀后缀的页面拼接格式
    @RequestMapping("/save5")
    public ModelAndView save5(ModelAndView modelAndView) {
        modelAndView.setViewName("redirect:page.jsp");
        return modelAndView;
    }
}
返回json数据
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/save")
    public void save(HttpServletResponse response) throws IOException {
        response.getWriter().write("返回json数据");
    }

    @RequestMapping("/save2")
    @ResponseBody //禁止页面跳转,返回的内容就是响应体
    public String save2() {
        return "json";
    }

    //返回json数据
    @RequestMapping("/save3")
    @ResponseBody
    public String save3() throws JsonProcessingException {
        User user = new User();
        user.setName("张三");
        user.setAge(22);
        String json = new ObjectMapper().writeValueAsString(user);
        return json;
    }

    //返回json数据
    @RequestMapping("/save4")
    @ResponseBody
    public User save4() {
        User user = new User();
        user.setName("张三");
        user.setAge(22);
        return user;
    }

    @RequestMapping("/save5")
    @ResponseBody
    public ArrayList<User> save5() {
        User user1 = new User();
        user1.setName("张三");
        user1.setAge(22);

        User user2 = new User();
        user2.setName("李四");
        user2.setAge(23);

        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(user1);
        arrayList.add(user2);
        return arrayList;
    }
}

需要注意:

@ResponseBody作用:禁止进行页面跳转。

如果返回的类型为对象类型,需要在配置文件中添加配置:

<mvc:annotation-driven/>

该配置,不仅仅是解决了@Controller注解使用的前提配置。还提供了:数据绑定支持。我们处理响应ajax请求时,就使用到了对json的支持。配置之后,在加入了jackson的core和mapper包之后,不写配置文件也能自动转换成json。

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页