SpringMVC(一)——SpringMVC入门程序

1 SpringMVC基本概念

1.1 三层架构

在JavaEE开发中,几乎全是B/S架构的开发。在B/S架构中,系统标准的三层架构包括:表现层、业务层、持久层。SpringMVC对应的就是表现层。
在这里插入图片描述
SpringMVC设计模型:

  • M:model 模型–javabean;
  • V:view 视图–jsp;
  • C:controller 控制器–servlet;

1.2 SpringMVC概述

1.2.1 SpringMVC是什么

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring 的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等。
SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。

1.2.2 SpringMVC在三层架构中的位置

在这里插入图片描述

2 SpringMVC入门程序

  • 创建Maven工程,勾选创建骨架,选择创建webApp骨架
    在这里插入图片描述

  • 创建的目录结构可能会缺少一些东西,完整结构如下:
    在这里插入图片描述

  • 配置servlet,web.xml

<web-app>
  <!-- 配置核心控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 使核心控制器初始化时读取bean.xml文件创建Spring核心容器 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
<!--      加载的配置文件-->
      <param-value>classpath:bean.xml</param-value>
    </init-param>
    <!-- 设置该Servlet的优先级别为最高,使之最早创建,在启动tomcat时启动servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

  • 配置bean.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">

    <!-- 配置spring创建容器时扫描的包 -->
    <context:component-scan base-package="com.wxy"></context:component-scan>

    <!-- 配置视图解析器,用于解析项目跳转到的文件的位置 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 配置spring开启注解mvc的支持 -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

  • 编写控制器
/**
 * 控制器
 */
@Controller //交给ioc控制
public class HelloController {
    @RequestMapping(path = "/hello") //指定方法对应URL
    public String helloHandler() {
        System.out.println("Hello SpringMVC!!!");
        //返回值默认表示jsp文件的名字
        return "success"; //指定跳转的视图地址,被ViewResolver解析为 /WEB-INF/pages/success.jsp
    }
}
  • 编写index.jsp和跳转jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
    <h3>入门案例</h3>
    <a href="hello">入门案例</a>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
    <h3>入门案例</h3>
    <a href="hello">入门案例</a>
</body>
</html>
  • 配置tomcat
    在这里插入图片描述
  • 运行

    在这里插入图片描述

2.1 请求的过程

SpringMVC框架是基于组件方式执行流程的。
在这里插入图片描述
执行过程分析:

  • 服务器启动,应用被加载。读取到web.xml中的配置创建spring容器并且初始化容器中的对象。
    (上面的案例中可以看出是HelloController和InternalResourceViewResolver,但是远不止这些)
  • 浏览器发送请求,被DispatherServlet捕获,该Servlet并不处理请求,而是把请求转发出去。转发的路径是根据请求URL,匹配@RequestMapping中的内容。
  • 匹配到之后,执行对应的方法。该方法返回一个返回值。
  • 根据方法的返回值,借助InternalResourceViewResolver找到对应的结果视图。
  • 渲染结果视图,响应浏览器。

2.2 SpringMVC中的组件

  • DispatcherServlet:前端控制器(dispatcher:调度员)

    • 用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
  • HandlerMapping:处理器映射器

    • HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  • Handler:处理器

    • 它就是我们开发中要编写的具体业务控制器。由DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
  • HandlAdapter:处理器适配器

    • 通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
  • View Resolver:视图解析器

    • View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
  • View:视图

    • SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是 jsp。
      一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
  • < mvc:annotation-driven>说明

    • 使 用 < mvc:annotation-driven> 自 动 加 载RequestMappingHandlerMapping ( 处 理 映 射 器 ) 和RequestMappingHandlerAdapter ( 处 理 适 配 器 ) , 可 用 在 SpringMVC.xml 配 置 文 件 中 使 用< mvc:annotation-driven>替代注解处理器和适配器的配置。一般开发中,我们都需要写上需要的标签

2.3 RequestMapping 注解

作用:用于建立请求URL和处理请求方法之间的对应关系。

出现的位置:

  • 类上:请求URL的第一级访问目录。此处不写的话就对应根目录;写的话需要 / 开头。作用是使我们的URL可以按照模块化管理。
  • 方法上,请求URL的第二级访问目录。
@Controller //交给ioc控制
@RequestMapping(path = "/user")
public class HelloController {
    /**
     * 保存用户,user/saveUser 访问
     * @return
     */
    @RequestMapping(path = "/saveUser") 
    public String saveUser() {
		//保存用户方法体
    }
    /**
     * 删除用户,user/deleteUser 访问
     * @return
     */
    @RequestMapping(path = "/deleteUser ") 
    public String deleteUser() {
		//删除用户方法体
    }

属性:

属性作用
value用于指定请求的URL。作用和path属性相同
method用于指定请求的方式,值有 RequestMethod.GET, RequestMethod.HEAD, RequestMethod.POST, 等
params用于指定限制请求参数的条件。要求请求参数的key和value和配置的相同。例如:
params={“accountName”},表示请求参数必须有accountName
params={“money!100”},表示请求参数中money不能是100(是用=)

3 请求参数的绑定

表单中的请求参数都是基于key=value的。
SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器方法参数进行的。

3.1 普通类型

支持的数据类型:

  • 基本类型参数:基本数据类型和String类型
  • POJO类型参数:实体类以及关联的实体类
  • 数组和集合类型参数:数组、list、map

SpringMVC绑定请求参数是自动实现的

使用

  • 基本类型数据:与参数名相同即可
    在这里插入图片描述
  • POJO类型:与属性名相同,如果属性也是POJO类型则用 属性名.属性名
  • 集合类型:List和数组用 变量名[0] 的形式,Map用 变量名[ key ] 的形式

在这里插入图片描述

3.2 请求参数乱码的问题

在传中文的时候会出现乱码的问题,可以通过配置web.xml来解决。
最好放在servlet标签之前,防止可能会报错

  <!--  配置解决中文乱码问题-->
  <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>

3.3 自定义类型转换器

SpringMVC可以将传的大多数字符串转成参数对应类型,在输入日期的时候,2020/8/12可以自动转成Date类型,但是2020-8-12不可以,这时可以通过自己定义一个类,实现Converter接口,实现自定义类型转换。

/**
 * 字符串转日期
 */
public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        if(source == null) {
            throw new RuntimeException("日期参数为空");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return df.parse(source);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

在bean.xml中配置该bean对象

<!--    配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
<!--                不会覆盖-->
                <bean class="com.wxy.utils.StringToDateConverter"></bean>
            </set>
        </property>
    </bean>
    <!-- 配置spring开启注解mvc的支持 -->
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

3.4 使用Servlet API对象作为方法参数

SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。
支持原始 ServletAPI 对象有:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale
  • InputStream
  • OutputStream
  • Reader
  • Writer

我们可以把上述对象,直接写在控制的方法参数中使用。

@RequestMapping("/testServletAPI") 
public String testServletAPI(HttpServletRequest request, 
       HttpServletResponse response, 
       HttpSession session) { 
	 System.out.println(request); 
	 System.out.println(response); 
	 System.out.println(session); 
	 return "success"; 
}

4 Spring 常用注解

4.1 RequestParam

作用:把请求中指定名称的参数给控制器的形参。

属性:

  • value:请求参数的名称
  • required:请求参数中是否必须提供此参数,默认为true,如果不提供则报错
<a href="anno/testRequestParam?username=王二狗">RequestParam</a><br>
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam("username") String name){
    System.out.println(name);
    return "success";
}

4.2 RequestBody

作用:用于获取请求题内容,直接得到“key=value&key=value…”这样的数据。get请求不适用。

属性:

  • required:是否必须有请求体。默认是true,get方法会报错,如果取值为false,get方法得到null。
    <form action="anno/testRequestBody" method="post">
        姓名:<input type="text" name="username"/><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="提交">
    </form><br>
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println(body);
        return "success";
    }

4.3 PathVariable

作用:

  • 用于绑定url中的占位符。例如:请求url中 /anno/testPathVariable/{id},这个{id}就是URL占位符。
  • url支持占位符是spring3.0之后加入的。是springmvc支持rest风格url的一个重要标志

属性:

  • value:用于指定url中占位符的名称
  • requeired:是否必须提供占位符
<a href="anno/testPathVariable/10">PathVariable</a><br>
    @RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable("id") String uid){
        System.out.println(uid);
        return "success";
    }

在这里插入图片描述

4.4 RequestHeader

作用:用于获取请求消息头(可以防爬虫)。
属性:

  • value:提供的消息头名称
  • required:是否必须有此消息头
<a href="anno/testRequestHeader">RequestHeader</a><br>
    @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader("Accept") String header){
        System.out.println(header);
        return "success";
    }

4.5 CookieValue

作用:用于把指定cookie名称的值传入控制器方法参数
属性:

  • value:指定cookie的名称
  • required:是否必须有此cookie
<a href="anno/testCookieValue">CookieValue</a><br>
	@RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue("JSESSIONID") String cookieValue){
        System.out.println(cookieValue);
        return "success";
    }

4.6 ModelAttribute

作用:

  • 该注解是springMVC4.3之后新加入的。可用于修饰方法和参数。
  • 出现在方法上,表示当前方法会在控制器之前执行。
  • 出现在参数上。获取指定的数据给参数赋值。

属性:

  • value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key

应用场景:

  • 当表单提交的数据不能完全赋值一个实体类时,可以让没有赋值的数据使用在数据库中该对象原来的数据。
    <form action="anno/testModelAttribute" method="post">
        姓名:<input type="text" name="username"/><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="提交">
    </form><br>

有返回值的方法(返回值直接赋值给控制器的参数user):

@ModelAttribute 
public User showModel(String username) { 
 //模拟去数据库查询 
 User abc = findUserByName(username); 
 System.out.println("执行了 showModel 方法"+abc); 
 return abc; 
} 

//控制器
    @RequestMapping("/testModelAttribute")
    public String testModelAttribute(User user){
        System.out.println("testModelAttribute执行了");
        return "success";
    }

无返回值的方法(要将查到的数据存入Map中,在控制器用通过map获取数据):

@ModelAttribute 
public void showModel(String username,Map<String,User> map) { 
 //模拟去数据库查询 
 User user = findUserByName(username); 
 System.out.println("执行了 showModel 方法"+user); 
 map.put("abc",user); 
} 
//控制器
@RequestMapping("/updateUser") 
public String testModelAttribute(@ModelAttribute("abc")User user) { 
 System.out.println("控制器中处理请求的方法:修改用户:"+user); 
 return "success"; 
}

4.7 SessionAttribute

作用:用于多次执行控制器方法之间的参数共享。

属性:

  • value:用于指定存入的属性名称
  • type:用于指定存入的数据类型
	<!-- 存session -->
    <a href="anno/testSessionAttributes">SessionAttributes</a>
    <!-- 查session -->
    <a href="anno/testgetSessionAttributes">getSessionAttributes</a>
    <!-- 删session -->
    <a href="anno/testdeleteSessionAttributes">deleteSessionAttributes</a>
 	@RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Model model){
        System.out.println("testSessionAttributes执行了");
        //底层会存储到Request域对象中去(不用HttpServletRequest,是因为耦合度太高)
        model.addAttribute("msg","美羊羊");
        return "success";
    }

    @RequestMapping("/testgetSessionAttributes")
    public String testgetSessionAttributes(ModelMap modelMap){
        System.out.println(modelMap.get("msg"));
        return "success";
    }

    @RequestMapping("/testdeleteSessionAttributes")
    public String testdeleteSessionAttributes(SessionStatus sessionStatus){
        sessionStatus.setComplete();
        return "success";
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值