springMVC总结

54 篇文章 0 订阅
48 篇文章 0 订阅

springMVC的核心就是DispatcherServlet程序,所有的请求都是先进入这个Servlet对象。 官方的图:
在这里插入图片描述

使用:
(1)准备log 和 spring的xml配置文件
(2)在web.xml中配置dispatchServlet

方式一:
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
	<servlet-name>springDispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
	<!-- 	给Spring的核心组件,告诉它,springMVC的配置文件在哪 -->
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springmvc.xml</param-value>
	</init-param>
	<!-- load-on-startup表示当前这个Servlet程序,当Web服务器一启动的时候,就创建和初始化 -->
	<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
	<servlet-name>springDispatcherServlet</servlet-name>
	<!-- / 拦截全部请求。/支持restful风格 -->
	<url-pattern>/</url-pattern>
</servlet-mapping>

方式二:

(1)在web.xml配置文件所在的目录下创建一个springMVC配置文件
(2)这个配置文件的命名规则:前段控制器servlet的名称+"-servlet.xml"


(3)@Controller的类中方法加 @RequestMapping注解 表示SpringMVC中注册一个控制器 return默认执行转发

**

springMVC中的各种注解 **

**RequestMapping注解**
	1 RequestMapping的value属性:   /表示到工程名  映射到代码的webcontent目录
					  params属性: 当前请求地址必须要有的参数
									params="username"			表示	请求地址必须带有username参数
									params="username=abc"	表示	请求参数中必须要有username,而且值还必须是abc
									params="username!=abc"	表示	1、请求参数中不能有username参数。2、有username参数,但值不能等于abc
									params="!username"		表示	请求地址不能带有username参数							
									params= {"username!=abc","!password"}	params可以有多个值,每个值之间是&&关系,表示要求:(	请求地址中不能有username参数 || username参数值不能等于 abc 	&& 	不能有password参数	)
						headers属性:可以限定请求头中的内容 ,例如可以限定某个版本的浏览器 
						method属性:method=RequestMethod.GET或者method=RequestMethod.POST 表示当前请求必须是GET或者POST才可以访问
						
	2@RequestMapping注解写在类上面表示这是一个controller控制器类,访问地址是:http://ip:port/工程名/Controller地址/方法上的地址
	
	3通配符在@RequestMapping中的使用:
	1绝对匹配:就是上面所写的方式
	2?问号:表示一个任意字符
	3*星号:可以匹配任意多个字符
	当一个路径同时匹配多个规则的时候,调用方法的优先顺序是:	
	绝对匹配--->>>>?问号匹配---->>>>*星号匹配
	4/?匹配一层目录并且只有一个字符  			 /*匹配一层目录多个字符 				/**匹配多层目录并且有多个字符
	 
## Controller类方法自动注入原生api##
	可以注入HttpServletRequest HttpSession HttpServletResponse等类 


## 普通参数入参##
	1可以通过注入request对象进而获取参数 但不推荐这个 
	2直接在方法上设置参数就可以获取了!~(要求参数名和方法的参数名一样)
				用数组接收多个值
	
	@RequestParam (value="aaa",required=false,defaultValue="ccc" )入参:
	springmvc会自动将请求过来的aaa参数注入进去,  required=false意味着可以不传递该参数默认是null,defaultValue是没有传递值的时候修改的默认值

## @RequestHeader获取请求头入参 ##
	@RequestHeader(value = "User-Agent") String userAgent,@RequestHeader(value = "Host") String host
	上面是方法的参数,可以注入请求头User-Agent Host等的值

## @CookieValue获取Cookie值入参 ##
	@CookieValue(value = "JSESSIONID") String jsessionid  可以注入cookie中的JSESSIONID

## 注入一个pojo对象类型的参数 ##
	直接在方法参数上写上你的对象

## 注入及联对象(对象中包含对象)的参数 ##
	表单写的参数就是 pojo1.pojo2 即可 

**

视图解析器

**

<!-- 配置Spring的视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- prefix配置返回的视图的前缀 -->
		<property name="prefix" value="/jsp/"/>
		<!-- suffix配置返回的视图的后缀 -->
		<property name="suffix" value=".jsp"/>
	</bean>

**

springMVC的返回值

**

1默认情况下,返回return字符串。会经过视图解析器做字符串前后缀拼接的操作,然后做转发操作
2显示地转发:
			// 在返回的字符串前面显示的标注 forward:表示显示的转发
			// 使用显示的转发,视图解析器就不会工作了
			绝对路径转发:return "forward:/jsp/return.jsp";
						/ 表示绝对路径http://ip:port/工程名/
						整个地址表示转发到http://ip:port/工程名/jsp/return.jsp
			
			
			相对路径转发:return "forward:jsp/return.jsp";
						当前浏览器地址栏地址是:http://localhost:8080/mvc_hello/p/return2
						相对路径是参数当前浏览器地址栏的地址
						得到的转发路径是:http://localhost:8080/mvc_hello/p/jsp/return.jsp
3显示地重定向:
			return "redirect:/jsp/return.jsp";    视图解析器不工作
			也有绝对路径和相对路径 跟2中的规则一样
4返回ModdelAndView
			// ModelAndView 也可以设置返回的资源
		ModelAndView modelAndView = new ModelAndView();
			// 设置视图名
		modelAndView.setViewName("return");    
		return modelAndView;
		默认的会经过试图解析器   同时也拥有显示转发和显示重定向 跟上面的一样
5返回void:
		1会直接请求相应的jsp  一般我们禁止这么使用
		2返回void的情况可以在参数中注入原生api然后进行相应代码操作

**

数据在域中的保存

**

Request对象中保存数据:
	方式一:参数中加一个HttpServletRequest对象 然后在方法中保存数据到request中再转发  (不推荐)
	方式二:参数中用Map或者Model或者ModelMap或者ModelAndView类型参数中存你的值 会自动保存到request中     推荐!~
					在参数中写 Map Model ModelMap三个接收的都是同一个对象BindingAwareModelMap隐含模型
					BindingAwareModelMap  
			 *            继承了
			 *      ExtendedModelMap    -----实现>>>>>>Model接口
						  继承了
			 *         ModelMap  
						  继承了
			 *       LinkedHashMap
						   继承了
			 *          HashMap  ------实现>>>>>> Map接口




Session中保存数据:
	方式一:参数中加一个HttpSession对象 然后在方法中保存数据到Session中再转发  (不推荐)

ServletContext域中保存数据:
			ServletContext不可以直接在参数中注入
		方式一:@autowired注入
		方式二:注入session  然后通过session.getServletContext()获取

**

@ModelAttribute注解

**

@ModelAttribute注解

@ModelAttribute这个注解可以标注在方法和参数上。
@ModelAttribute三个常见作用:
(1)被标注了@ModelAttribute的方法都会在Controller的目标方法之前执行。
(2)因为目标方法的参数(JavaBean对象)会先从隐含模型中获取值传入,所以我们可以在被标注了@ModelAttribute的方法参数写好隐含模型,并且在方法中赋值
(3)目标方法中,如果有对象参数(非原生API,是那些pojo对象),它会先按照参数的类型取类名,然后首字母小写,从隐含模型中取值注入。利用@ModelAttribute注解标注在参数上,参数值会按照指定的key从隐含模型中获取值。

**

springMVC乱码解决

**

POST请求乱码需要加一个filter过滤器:
<filter>
		<!-- 配置Filter解决post请求乱码 -->
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<!-- 配置post请求进来的字符集 -->
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<!-- 配置响应的字符集 -->
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

GET请求乱码在tomcat的server.xml配置文件中做如下的配置:

在这里插入图片描述
**

springMVC中静态资源请求问题

**

因为springMVC中的前段控制器的拦截地址跟服务器的默认静态资源地址冲突了 所以会有静态资源请求无效的情况 需要做:
	<!-- 配置Spring支持静态资源请求 -->
	<mvc:default-servlet-handler/>   加了这个就只支持静态资源了!
	<!-- 启用SpringMVC注解驱动 -->
	<mvc:annotation-driven></mvc:annotation-driven> 
这个是springMVC的标配,加了上面两个后就会先检查是否匹配注解的资源(controller)不匹配再找静态资源

**

Restful风格

一种软件设计风格
**

1、把请求参数加入到请求的资源地址中
2、原来的增,删,改,查。使用HTTP请求方式,POST、DELETE、PUT、GET分别一一对应。
		GET请求		对应    查询
		http://ip:port/工程名/book/1		HTTP请求GET		表示要查询id为1的图书
		http://ip:port/工程名/book			HTTP请求GET		表示查询全部的图书
		
		POST请求	对应	添加
		http://ip:port/工程名/book			HTTP请求POST		表示要添加一个图书
		
		PUT请求		对应	修改
		http://ip:port/工程名/book/1		HTTP请求PUT		表示要修改id为1的图书信息
		
		DELETE请求	对应	删除
		http://ip:port/工程名/book/1		HTTP请求DELETE		表示要修改id为1的图书信息

使用:restful风格可以直接使用 controller中的@RequestMapping注解的method方法写好相应的请求类型

		 发起PUT请求和DELETE请求:
		1、要有post请求的form标签
		2、在form表单中,添加一个额外的隐藏域_method=”PUT”或_method=”DELETE”
		3、在web.xml中配置一个Filter过滤器org.springframework.web.filter.HiddenHttpMethodFilter(注意,这个Filter一定要在处理乱码的Filter后面 否则会导致乱码的filter无效就会有乱码产生 )因为HiddenHttpMethodFilter在它的doFilterInternal方法中首先就用了request.getParameter方法来获取你的_method参数  我们知道post请求解决乱码的代码request.setCharacterEncoding需要在request.getParameter方法之后的~

在高版本的tomcat中跳转会有405问题:
	方法一:修改jsp页面中的page指令isErrorPage="true",就可以访问了

		<%@ page language="java" contentType="text/html; charset=UTF-8"
			isErrorPage="true"
			pageEncoding="UTF-8"%>

	方法二:把转发改成为重定向redirect:/

@PathVariable 路径参数获取
			requestMapping中value写成 .../{参数} 然后用@PathVariable将变量注入到你的参数中
第一种情况,一个path参数:
			注意:@PathVariable标记的路径变量,不能为空,必须有值
第二种情况,多个path参数:一般不这么使用

**

SpringMVC的标签库

一般也不用
**

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>这是springmvc的标签

 
			springMVC的标签form标签可以关联Request域中bean对象(类名首字母小写)
			我们在隐含模型中保存的key值。也一定要跟form:form标签中的modelAttribute值对应上。
		 
		这是添加用户页面
		<form:form action="${ pageContext.request.contextPath }/addPerson" method="delete" 
			modelAttribute="person">
		name:<form:input path="name"/><br/>
<%-- 		birthDate:<form:input path="birthDate"/><br/> --%>birthDate有问题 因为没有相应的转换器能把String转换成java的Date类型 需要我们自定义~
		email:<form:input path="email"/><br/>
		salary:<form:input path="salary"/><br/>	
		<input type="submit" />		
		</form:form>
有挺多缺点且相对而言麻烦 好处就在于上述标签是会自动解析的

*******自定义类型转换器***********:
1自己代码实现的方式
(1)实现Converter接口
		可以仿照java源码进行转换 成功的话就返回Date类型
(2)注入到ConversionService中 
		在容器中配置FormattingConversionServiceFactoryBean类  来创建ConversionService组件 用来类型转换
		<bean>
				<property name="converters">
					<set>
						<bean class="你的自定义converter类">
					</set>
				</property>
		</bean>
(3)将ConversionService注入到WebDataBinder中
			这个功能在springmvc注解驱动中进行操作:
			<mvc:annotation-driven conversion-service="FormattingConversionServiceFactoryBean的id"></mvc:annotation-driven >
			成功转换后就会通过bean的set方法注入你的date类型啦!

2注解方式:
	在你的类里面的Date类型参数上写注解:@DateTimeFormat(pattern="string的格式")



**********利用Hibernate-Validate进行字段校验 并且进行错误信息的回显***********
@AssertTrue	用于boolean字段,该字段只能为true  
@AssertFalse	该字段的值只能为false
@CreditCardNumber	对信用卡号进行一个大致的验证
@DecimalMax	只能小于或等于该值
@DecimalMin	只能大于或等于该值
@Digits(integer=,fraction=)	检查是否是一种数字的整数、分数,小数位数的数字
@Email	检查是否是一个有效的email地址
@Future	检查该字段的日期是否是属于将来的日期
@Length(min=,max=)	检查所属的字段的长度是否在min和max之间,只能用于字符串
@Max	该字段的值只能小于或等于该值
@Min	该字段的值只能大于或等于该值
@NotNull	不能为null
@NotBlank	不能为空,检查时会将空格忽略
@NotEmpty	不能为空,这里的空是指空字符串
@Null	检查该字段为空
@Past	检查该字段的日期是在过去
@Pattern(regex=,flag=)	被注释的元素必须符合指定的正则表达式
@Range(min=,max=,message=)	被注释的元素必须在合适的范围内
@Size(min=, max=)	检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等
@URL(protocol=,host,port)	检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件

(1)导入包后在bean对象上使用校验的注解
(2)在Controller的方法参数上,给需要验证的bean对象。添加验证注解@Valid,以及在验证对象后跟一个BindingResult 对象用于接收验证的错误信息	错误信息可以在controller方法中进行操作
(3)利用springMVC的注解进行错误信息的回显:<form:errors path="跟前面的name一样">

*********自定义错误信息*********
(1)写一个properties文件 键值对 键是下面的字段 值是你自定义语句
(2)配置ResourceBundleMessageSource的bean让spring容器去加载自定义的错误信息  id就是messageSource   属性property name=“basename” value=“1中properties配置文件无后缀名”

**************错误信息中占位符的作用********** 
	可以自动传递参数进来
	{0}表示第一个传入的参数。 {0}第一个参数固定是验证的属性名 以此类推

**

文件上传

**

分四个步骤:
1、准备一个文件上传的表单
		method="post" enctype="multipart/form-data"
2、导入文件上传需要的jar包
commons-fileupload-1.2.1.jar、commons-io-1.4.jar
3、配置文件上传解析器	CommonsMultipartResolver
<!-- 配置在SpringMVC中解决文件上传的协议的解析器
			id 必须是multipartResolver  (主要功能接口的首字母小写)
	 -->
	<bean id="multipartResolver" 
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 配置字符集为UTF-8 -->
		<property name="defaultEncoding" value="UTF-8" />
	</bean>

4、配置Controller控制器的代码
		用MultipartFile进行文件的接收 
		有isEmpty tansferto  getOriginalFilename方法

**

相关注解

**

1 @ResponseBody  加了这个注解的意义就在于return之后返回的是json而不是跳转地址了
	(1)、导入json相关的包到web工程中    
	jackson-annotations-2.1.5.jar
	jackson-core-2.1.5.jar
	jackson-databind-2.1.5.jar
	(2)、编写一个请求的方式接收请求,并返回数据对象
	(3)、在方法上添加注解@ResponseBody自动将返回值json化

2 @JsonFormat修改时间在json中的格式
		@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 加在Date属性上或者Date的get方法上

3@RequestBody接收POST请求中的请求体数据
 				将此注解加在String字符串前面即可
 				
4使用HttpEntity参数获取请求头和请求体
				接收的参数就是HttpEntity类对象即可
 		 httpEntity.getHeaders()        httpEntity.getBody()
 		 
5使用ResponseEntity返回值操作响应头和响应体   **************实现文件的下载****************~~
		@RequestMapping(value = "/download")
	public ResponseEntity<byte[]> download(HttpSession session) {
		try {
			ServletContext ctx = session.getServletContext();  //通过session 获取 ServletContext
			InputStream is = ctx.getResourceAsStream("/WebContent目录下你的资源");
			byte[] buffer;
			buffer = new byte[is.available()];
			is.read(buffer);
			is.close();
		 
			String mimeType = ctx.getMimeType("/WebContent目录下你的资源");获取数据类型
			
			// 响应头的目的就是告诉我返回的类型是什么 以及 如何操作我返回的东西
			HttpHeaders httpHeaders = new HttpHeaders();
			httpHeaders.add("Content-Type", mimeType);
			httpHeaders.add("Content-Disposition", "attachment; filename=下载的文件名.jpg");
			// 第一个参数是你要返回的数据--我们要实现文件下载,就需要把下载的文件字节内容都放body中
			// 第二个参数是 响应头
			// 第三个参数是你要返回的响应状态码和响应 状态描述 符
			ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(
					buffer, httpHeaders, HttpStatus.OK);

			return responseEntity;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
大功告成!~

**

HandlerInterceptor拦截器

可以拦截controller方法包括内部映射的 不拦截直接的jsp请求
**

1、编写一个类去实现HandlerInterceptor接口
			三个方法:preHandle  在目标方法执行前调用  return true表示放行
							 postHandle  在目标方法执行后调用  
							 afterCompletion  目标方法执行完 跳完页面渲染完之后调用
2、到Spring的容器配置文件中去配置拦截器,并且配置拦截地址
			<mvc:interceptors>  里头可以配置多个拦截器			 
				<mvc:interceptor>一个这个标签算一个
					<!-- 拦截的地址 -->
					<mvc:mapping path="/一般可以是你的controller地址"/>
					<!-- 拦截器具体实现类 -->
					<bean class="你的拦截器类" />
				</mvc:interceptor>
			</mvc:interceptors>	

正常情况下拦截器的执行顺序:
  preHandle  目标方法执行  postHandle   页面渲染的代码   afterCompletion

出现异常的情况下拦截器的执行顺序:
	一:目标方法前返回false的情况:

	1、目标方法前执行 		返回false
	2、这是目标方法			不执行
	3、目标方法之后			不执行
	4、这是渲染页面			不执行
	5、页面渲染完成!			不执行
	
	
	二:目标方法前返回true的情况,目标方法异常
	
	1、目标方法前执行 		返回true
	2、这是目标方法			异常
	3、目标方法之后			不执行
	4、这是渲染页面			渲染异常页面
	5、页面渲染完成!			执行
	
	
	三:目标方法前返回true的情况,目标方法后异常
	
	1、目标方法前执行 		返回true
	2、这是目标方法			执行
	3、目标方法之后			异常
	4、这是渲染页面			渲染异常页面
	5、页面渲染完成!			执行
	
	
	四:目标方法前返回true的情况,渲染页面异常
	
	1、目标方法前执行 		返回true
	2、这是目标方法			执行
	3、目标方法之后			执行
	4、这是渲染页面			异常
	5、页面渲染完成!			执行

**

使用@ExceptionHandler拦截异常

**

拦截本controller中的异常(局部异常):
 	(1)controller中写一个方法 加上@ExceptionHandler注解  返回值是你要去的异常页面 参数是Exception对象 可以用modelAnd
View保存错误信息 转发过去错误页面就可以显示异常信息了!~
	(2)controller中可以有多个(1)中的异常方法 异常类型越精确就越优先处理

@ControllerAdvice它可以处理所有Controller中产生的异常(全局异常) 即所有controller中的异常都可以处理
		(1)加载类上面   (2)方法同样需要写@ExceptionHandler      也适用多个错误控制 越精确越优先!

在局部异常处理和全局异常处理同时存在的时候,优先顺序是:
	1、局部优先	---->>>>	2、精确优化

**

配置SimpleMappingExceptionResolver类映射异常

**

<!-- 配置SimpleMappingExceptionResolver简单异常映射解析器 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<!-- 异常映射属性 固定值的 -->
		<property name="exceptionMappings">
			<props>
				<!-- 
					key写上异常全类名
					在prop标签中填写那批的跳转地址
				 -->
				<prop key="java.lang.Exception">forward:/error.jsp</prop>
				<prop key="java.lang.RuntimeException">forward:/error.jsp</prop>
				<prop key="java.lang.ArithmeticException">forward:/error1.jsp</prop>
				<prop key="java.lang.NullPointerException">forward:/null.jsp</prop>
			</props>
		</property>
	</bean>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值