springmvc学习笔记(一)

本文深入讲解SpringMVC框架,涵盖其架构、处理流程、参数绑定等核心概念,对比Struts2,强调SpringMVC在Java Web开发中的优势。

目录

 

一、springmvc介绍

1.1 springmvc是什么

1.2 springmvc的处理流程

1.3 入门程序

二、springmvc的架构

2.1 框架结构

2.2 架构流程

2.3 组件说明

2.4 组件扫描器

2.5 注解映射器和适配器

2.6 视图解析器

三、参数绑定

3.1 默认支持的参数类型

3.2 绑定简单类型

四、springmvc与struts2不同


一、springmvc介绍

1.1 springmvc是什么

springmvc是一套表现层的框架,是用来开发javaweb的,它和struts差不多,属于spring家族中的一员。

1.2 springmvc的处理流程

核心是一个DispathcerServlet来分发请求。

1.3 入门程序

1.3.1 创建一个web工程,添加一下jar包

1.3.2 添加springmvc.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-4.0.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-4.0.xsd">

	<!-- 配置controller扫描包 -->
	<context:component-scan base-package="cn.itcast.springmvc.controller" />

</beans>

1.3.2 添加web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">

	<!-- 配置SpringMVC前端控制器 -->
	<servlet>
		<servlet-name>springmvc-first</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 指定SpringMVC配置文件 -->
		<!-- SpringMVC的配置文件的默认路径是/WEB-INF/${servlet-name}-servlet.xml -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
	</servlet>

	<servlet-mapping>
		<servlet-name>springmvc-first</servlet-name>
		<!-- 设置所有以action结尾的请求进入SpringMVC -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

1.3.3 添加IndexController和index.jsp

IndexController.java

package cn.itcast.springmvc.controller;

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

@Controller
public class IndexController {
	@RequestMapping("/index")
	public ModelAndView index() {
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", "hello,springmvc");
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("/WEB-INF/jsp/index.jsp");
		return modelAndView;
	}

}

index.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
       ${msg}
  </body>
</html>

1.3.4 启动tomcat服务器,浏览器访问 http://localhost:8080/spring-mvc/index,出现

二、springmvc的架构

2.1 框架结构

框架结构图如下:

2.2 架构流程

1.用户发送请求至前端控制器DispatherServlet。

2.DispatherServlet收到请求代用HandlerMapping处理器映射器。

3.处理器映射器,也就是映射器,它是用来找处理器的,是根据请求url找到具体的处理器也就是Controller,生成处理器及处理器拦截器并一起返回给DispatherServlet。

4.DispatherServlet通过HandlerAdapter处理器适配器调用处理器(controller)

5.执行处理器,也就是controller。

6.Controller执行后返回ModelAndView

7.HandlderAdapter将Controller执行结果ModelAndView返回给DispatherServlet。

8.DispatherServlet将ModelAndView传给ViewReslover视图解析器。

9.ViewReslover解析后返回具体的View。

10.DispatherServlet对View进行渲染视图(即将模型数据填充至视图中)。

11.响应给用户。

2.3 组件说明

DispatherServlet:前端控制器

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

HandlerMapping:处理器映射器

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

Handler:处理器

Handler是继DispatherServlet前端控制器的后端控制器,再DispatherServlet的控制下,Handler对具体的用户请求进行处理。由于Handler设计具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。也就是Controller。

HandlerAdapter:处理器适配器

通过HandlerAdapter处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

ViewReslover:视图解析器

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

View:视图

springmvc框架提供了很多的view视图类型的支持,包括:jstlView、freemarkerView,pdfView等。我们最常用的视图就是jspView.

说明:在springmvc中的各个组件中,处理器映射器、处理器适配器、视图解析器成为springmvc的三大组件。需要用户开发的组件有handler、view

2.4 组件扫描器

使用组件扫描器省去在spring容器配置每个Controller类的繁琐。使用<context:component-scan>自动扫描标记@Controller的控制器类,在springmvc.xml下配置如下:

<!-- 配置controller扫描包,多个包之间用,分隔 -->

<context:component-scan base-package="cn.itcast.springmvc.controller" />

2.5 注解映射器和适配器

2.5.1 配置处理器映射器

注解式处理器映射器,对类中标记了@RequestMapping的方法进行映射。根据@RequestMapping定义的url匹配@RequestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。HandlerMethod对象中封装url对应的方法Method。

在springmvc.xml配置文件中配置如下:

<!-- 配置处理器映射器 -->

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

注解描述:

@RequestMapping定义请求url到处理器功能方法的映射

2.5.2 配置处理器适配器

注解式处理器适配器,对标记@RequestMapping的方法进行适配。

从spring3.1版本开始,废除了AnnotationMethodHandlerAdapter的使用,推荐使用RequestMappingHandlerAdapter完成注解式处理器适配。

 

在springmvc.xml配置文件中配置如下:

<!-- 配置处理器适配器 -->

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />

2.5.3 注解驱动

直接配置处理器映射器和处理器适配器比较麻烦,可以使用注解驱动来加载。

SpringMVC使用<mvc:annotation-driven>自动加载RequestMappingHandlerMapping和RequestMappingHandlerAdapter

可以在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置。

<!-- 注解驱动 -->

<mvc:annotation-driven />

2.6 视图解析器

视图解析器使用springmvc框架默认的InternalResourceResolver,这个视图解析器支持jsp视图解析。

配置如下:

<!-- 配置视图解析器 -->

    <bean

       class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <!-- 配置逻辑视图的前缀 -->

       <property name="prefix" value="/WEB-INF/jsp/" />

       <!-- 配置逻辑视图的后缀 -->

       <property name="suffix" value=".jsp" />

    </bean>

<?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-4.0.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-4.0.xsd">

	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<context:component-scan base-package="cn.itcast.springmvc.controller" />	
</beans>

三、参数绑定

3.1 默认支持的参数类型

处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值

通过request对象获取请求信息 HttpServletRequest

通过response对象处理响应信息 HttpServletResponse

通过session对象得到session中存放的对象

@Controller
public class IndexController {
	@RequestMapping("/index")
	public ModelAndView index(HttpServletRequest request,HttpServletResponse response) {
		
		String id =  request.getParameter("id");
		System.out.println(id);
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", "hello,springmvc id:"+request.getParameter("id"));
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("index");
		
		return modelAndView;
	}

}

3.2 绑定简单类型

3.2.1 当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定

这样,从Request取参数的方法就可以进一步简化。

@Controller
public class IndexController {
	@RequestMapping("/index")
	public ModelAndView index(int id,String name) {
		
		
		System.out.println(id);
		System.out.println(name);
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", "hello,springmvc id:"+id+","+name);
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("index");
		
		return modelAndView;
	}

}

3.2.2 参数类型推荐使用包装数据类型,因为基础数据类型不可以为null 

整形:Integer、int

字符串:String

单精度:Float、float

双精度:Double、double

布尔型:Boolean、boolean

说明:对于布尔类型的参数,请求的参数值为true或false。或者1或0

3.3.3 @RequestParam

使用@RequestParam常用于处理简单类型的绑定,该注解有以下两个参数

value:参数名字,即入参的请求参数名字,如value=“itemId”,便是请求的参数区中的名字为itemId的参数值将传入

required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错

TTP Status 400 - Required Integer parameter 'XXXX' is not present

defaultValue:默认值,表示如果请求中没有同名参数时的默认值

	@RequestMapping("/index2")
	public ModelAndView index2(
			@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id) {
		System.out.println(id);
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", id);
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("index");
		return modelAndView;
	}

3.3.4 绑定pojo类型

pojo类型

package cn.itcast.springmvc.pojo;

import java.util.Date;

public class Item {
	// 商品id
	private int id;
	// 商品名称
	private String name;
	// 商品价格
	private double price;
	// 商品创建时间
	private Date createtime;
	// 商品描述
	private String detail;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public Date getCreatetime() {
		return createtime;
	}
	public void setCreatetime(Date createtime) {
		this.createtime = createtime;
	}
	public String getDetail() {
		return detail;
	}
	public void setDetail(String detail) {
		this.detail = detail;
	}
	@Override
	public String toString() {
		return "Item [id=" + id + ", name=" + name + ", price=" + price
				+ ", createtime=" + createtime + ", detail=" + detail + "]";
	}

}

editItem.jsp

<form id="itemForm"	action="${pageContext.request.contextPath }/updateItem" method="post" 
	<table width="100%" border=1>                                                         
		<tr>                                                                              
			<td>商品名称</td>                                                                 
			<td><input type="text" name="name" value="${item.name }" /></td>              
		</tr>                                                                             
		<tr>                                                                              
			<td>商品价格</td>                                                                 
			<td><input type="text" name="price" value="${item.price }" /></td>            
		</tr>                                                                             
					                                                                      
		<tr>                                                                              
			<td>商品简介</td>                                                                 
			<td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>     
			</td>                                                                         
		</tr>                                                                             
		<tr>                                                                              
			<td colspan="2" align="center"><input type="submit" value="提交" />             
			</td>                                                                         
		</tr>                                                                             
	</table>                                                                                                                                                                   </form>                                                                                   

控制器方法

@RequestMapping("/updateItem")
public ModelAndView updateItem(Item item) {	
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", item);
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("success");
		System.out.println(item);
		return modelAndView;
}

3.3.5 绑定复杂pojo类型

pojo类型

package cn.itcast.springmvc.pojo;

public class QueryVo {

	private String condition;
	private Item item;

	public Item getItem() {
		return item;
	}

	public String getCondition() {
		return condition;
	}

	public void setCondition(String condition) {
		this.condition = condition;
	}

	public void setItem(Item item) {
		this.item = item;
	}

	@Override
	public String toString() {
		return "QueryVo [condition=" + condition + ", item=" + item + "]";
	}
	
}

queryVoItem.jsp

	<form id="itemForm"	action="${pageContext.request.contextPath }/queryVo" method="post" >
		<table width="100%" border=1>
			<tr>
				<td>商品名称</td>
				<td><input type="text" name="item.name" value="" /></td>
			</tr>
			<tr>
				<td>商品价格</td>
				<td><input type="text" name="item.price" value="" /></td>
			</tr>
						
			<tr>
				<td>商品简介</td>
				<td><textarea rows="3" cols="30" name="item.detail"></textarea>
				</td>
			</tr>
			<tr>
				<td>查询条件</td>
				<td><textarea rows="3" cols="30" name="condition"></textarea>
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center"><input type="submit" value="提交" />
				</td>
			</tr>
		</table>

	</form>

控制器代码

	@RequestMapping("/queryVoItem")
	public ModelAndView queryVoItem() {
		
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", "hello,springmvc");
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("queryVoItem");

		return modelAndView;
	}
	
	@RequestMapping("/queryVo")
	public ModelAndView queryVo(QueryVo vo) {
		
		// 创建ModelAndView,用来存放数据和视图
		ModelAndView modelAndView = new ModelAndView();
		// 设置数据到模型中
		modelAndView.addObject("msg", vo);
		// 设置视图jsp,需要设置视图的物理地址
		modelAndView.setViewName("success");
		System.out.println(vo);
		return modelAndView;
	}

3.3.6 解决post乱码问题

提交发现,保存成功,但是保存的是乱码,在web.xml中加入:

	<!-- 解决post乱码问题 -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<!-- 设置编码参是UTF8 -->
		<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>

对于get请求中文参数出现乱码解决方法有两个:

修改tomcat配置文件添加编码与工程编码一致,server.xml文件 如下:

<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

 

另外一种方法对参数进行重新编码:

String userName new

String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

3.3.7 自定义参数绑定

由于日期数据有很多种格式,springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。

前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。可以在springmvc处理器适配器上自定义转换器Converter进行参数绑定

一般使用<mvc:annotation-driven/>注解驱动加载处理器适配器,可以在此标签上进行配置。

自定义日期格式的参数绑定 DateConverter

package cn.itcast.springmvc.converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

public class DateConverter implements Converter<String, Date> {
	@Override
	public Date convert(String source) {
		try {
			// 把字符串转换为日期类型
			System.out.println(source);
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date =  simpleDateFormat.parse(source);
			return date;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 如果转换异常则返回空
		return null;
	}
}

配置springmvc.xml

<mvc:annotation-driven conversion-service="conversionService" />                                                
<!-- 转换器配置 -->                                                                                                  
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 
	<property name="converters">                                                                                
		<set>                                                                                                   
			<bean class="cn.itcast.springmvc.converter.DateConverter" />                                        
		</set>                                                                                                  
	</property>                                                                                                 
</bean>                                                                                                         

四、springmvc与struts2不同

4.1 spring的入口是一个servlet即前端控制器,而struts2入口是一个filter过滤器

4.2 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例,struts是基于类开发,传递参数是通过类的属性,只能设计为多例。

4.3 struts采用值栈存储请求和响应的数据,通过ognl存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。jsp视图解析器默认使用jstl。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值