对springMVC的深入认识

本文详细介绍了SpringMVC的框架结构,从用户请求到响应的处理流程,包括DispatcherServlet的作用、处理器映射器与适配器、注解如@Controller、@RequestMapping的使用,以及请求参数绑定的多种方式。此外,还讲解了@RequestBody和@ResponseBody注解在JSON数据交互中的应用,以及SpringMVC的拦截器机制。通过对这些核心概念的深入理解,有助于提升SpringMVC的开发技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、MVC设计模式(这里讲的是b/s情况下的模式)


2、springMVC框架与spring的关系

springMVC只是spring框架的一个模块;如下图是spring整个框架的内容:


3、springMVC的框架结构原理


1、 用户发起请求,请求到DispatcherServlet前端控制器

DispatcherServlet(中央调度),负责requestresponse,负责调用处理器映射器查找Handler,负责调用处理器适配器执行Handler,有了前端控制器降低了各各组件之间的耦合性,系统扩展性提高。

2、 DispatcherServlet前端控制器请求处理器映射器HandlerMapping查找Handler

根据用户请求的url,根据一定的规则去查找(比如:xml配置,注解)

3、 HandlerMapping处理器映射器将Handler返回给前端控制器

4、 DispatcherServlet前端控制器调用HandlerAdapter处理器适配器执行Handler

程序员编写的Handler是按照适配器要求的规则去执行Handler

 

5、 HandlerAdapter处理器适配器执行Handler

适配器按照一定规则去执行Handler

6、 Handler执行完成,返回ModelAndView

ModelAndViewspringmvc的封装对象,将modelview封装在一起。

7、 HandlerAdapter处理器适配器将ModelAndView返回给前端 控制器

 

8、 前端控制器调用视图解析器,进行视图解析,解析完成给前端控制器返回View

Viewspringmvc的封装对象,是一个接口,实现类包括jspviewpdfview。。。。

9、 前端控制器调用view进行视图渲染

将模型数据填充到view(将model数据填充到request)响应给用户

10、前端控制器响应给用户。

4、这里详细的说明一下springmvc平常要了解的(开发是不常用的,一般都是用注解)三大组件:

1、处理器映射器常用的两个是(在注解开发中就是指的requestMapping注解):


<!-- 处理器映射器 根据url匹配bean的name 处理器映射器实现了HandlerMapping接口 -->
	<bean
		class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />

	<!-- 简单url映射的处理器映射器 -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/hello1.action">hello_controller</prop>
				<prop key="/hello2.action">hello_controller</prop>
				<prop key="/hello3.action">hello_controller3</prop>
			</props>
		</property>
	</bean>

对应的controller类的配置:

        <!-- 配置action -->
	<bean id="hello_controller" name="/helloworld.action" class="cn.itcast.springmvc.Hello" />
	
	<!-- 配置action -->
	<bean id="hello_controller3"  class="cn.itcast.springmvc.Hello1" />


根据处理器映射器就可以找到对应的handler(函数)

package cn.itcast.springmvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

/**
 * 
 * <p>Title: Hello</p>
 * <p>Description: 使用SimpleControllerHandlerAdapter适配器</p>
 * <p>Company: www.itcast.com</p> 
 * @author	
 * @version 1.0
 */
public class Hello implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		
		modelAndView.addObject("message", "helloworld!!!!!!");
		
		//响应到jsp的逻辑试图
		
		//modelAndView.setViewName("/WEB-INF/jsp/hello.jsp");
		
		return modelAndView;
	}

}

2、了解两个处理器适配器(实际上就是我们在使用springmvc的controller注解)

        <!-- 处理器适配器 实现了HandlerAdapter接口 action按照适配器要求开发 ,规则是实现Controller接口 -->
	<bean
		class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

	<!-- 配置HttpRequestHandlerAdapter处理器适配器 -->
	<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />

使用不同的适配器在MVC的C层的类需要实现不同的接口

使用SimpleControllerHandlerAdapter适配器,就要使用SimpleControllerHandlerAdapter适配器的规则进行处理

/**
 * 
 * <p>Title: Hello</p>
 * <p>Description: 使用SimpleControllerHandlerAdapter适配器</p>
 * <p>Company: www.itcast.com</p> 
 * @author	
 * @version 1.0
 */
public class Hello implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		//下面的方法就相当于request.setAttribute("message", message);
		modelAndView.addObject("message", "helloworld!!!!!!");
		return modelAndView;
	}


}


使用 使用HttpRequestHandlerAdapter适配器,就要使用HttpRequestHandlerAdapter适配器的规则进行处理
/**
 * 
 * <p>Title: Hello1</p>
 * <p>Description: 使用HttpRequestHandlerAdapter</p>
 * <p>Company: www.itcast.com</p> 
 * @version 1.0
 */

public class Hello1 implements HttpRequestHandler {

	@Override
	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		//向页面显示一行提示信息
		String message = "hellworld1";
	    request.setAttribute("message", message);
	    
	    //指定转向页面,使用request指定页面完整路径
	    request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request, response);
		
	}

}

3、视图解析器

<!-- 视图解析器 解析jsp视图,默认使用jstl,要求classpath下有jstl的jar包 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 视图的前缀 -->
		<property name="prefix" value="/WEB-INF/jsp/" />
		<!-- 视图的后缀 -->
		<property name="suffix" value=".jsp" />

	</bean>

这样使用视图解析器,就可以在controller层直接使用逻辑视图名称进行页面的响应:

modelAndView.setViewName("hello");

这里可以参考git仓库资源中的源码: 点击打开链接


5、针对springMVC在平常的开发中注解使用如下:

1、@controller

标识该类为控制器类,@controller@service@repository分别对应了web应用三层架构的组件即控制器、服务接口、数据访问接口

2、 @RequestMapping

进行url映射,一个方法对应一个url,定义方法:在action方法上定义requestMapping


3、在平常的开发中会使用 根路径+子路径 来辨别action的URL



4、 URI模板模式映射

(使用url的模板式映射的思想是:让每一条资源数据都有唯一的一个URL路径)


5、请求方法限定


可以限定为getpost、或两者都可以

限定GET方法

@RequestMapping(method = RequestMethod.GET)

如果通过Post访问则报错:

HTTP Status 405 - Request method 'POST' not supported

 

例如:

@RequestMapping(value="/useredit/{userid}",method=RequestMethod.GET)

限定POST方法

@RequestMapping(method = RequestMethod.POST)

如果通过Post访问则报错:

HTTP Status 405 - Request method 'GET' not supported

 

GETPOST都可以

@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})

6、springMVC的请求参数绑定(重点)

这里请求的参数绑定在handler处理器的形式参数中(Springmvc 通过参数解析器,将客户端请求的 key/value 解析成方法形参数);

参数解析器

Spring提供了很多参数解析器,将key/value的数据解析成形参,通过反射解析method中的参数(类型、名称),按照类型和名称规则解析形参;

属性编辑器:

key/value转换成pojo中的属性

6.1 默认支持的参数类型

 

  • HttpServletRequest
  • 通过request对象获取请求信息
  • HttpServletResponse
  • 通过response处理响应信息
  • HttpSession
  • 通过session对象得到session中存放的对象
  • Model
  • 通过model向页面传递数据,如下:
  •  
  • model.addAttribute("user",new User("李四"));
  •  
  • model也可以通过modelMapmap将数据传到页面。

6.2 表单对象-简单数据类型

 

Action方法的形参数默认支持:stringintdouble等简单类型,建议使用包装类型(可以设置null)。

注意:对于date类型的参数需要注册属性编辑器。

 

使用方法:

直接在形参上定义

也可以在pojo中通过属性传递简单类型


6.3表单对象-pojo类型

第一种,不需要封装目标bean



第二种需要对bean封装一次



6.4 字符串数组绑定



6.5、 List绑定参数类型

页面向action传递复杂的批量数据,比如学生的成绩信息(课程名称、成绩)

页面定义:


Scores:包装对象中list属性的名称

Coursename:包装对象中listpojo的属性名称。

Score:包装对象中listpojo的属性名称。

如果上边下标相同的CoursenameScore设置在一个pojo中。

 

 

Action方法定义:

使用List<pojo>接收上边的接收,pojo中包括上边课程名称(coursename)和成绩(score)


6.6、 @RequestParam绑定单个请求参数

value参数名字,即入参的请求参数名字,如value=“studentid表示请求的参数区中的名字为studentid的参数的值将传入;

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

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

 

需求

学生查询方法中必须要有一个参数group(学生分组)

 

实现:

 




7、 springMVC中结果转发


Redirect:请求重定向

浏览器中地址栏的url通过Redirect变了,重新定义了一个request

Action方法通过Redirect重定向到另一个方法,方法形参无法带到另一个方法。

定义方法:

 

//请求重定向
return "redirect:querystudent.action";

Forward:页面转发

浏览器中地址栏的url通过Forward不变,没有重新定义了一个request

    Action方法通过Forward转发到另一个方法,方法形参可以带到另一个方法。

 

定义方法:

 

//页面转发
return "forward:querystudent.action";


8、springMVC中 @RequestBody @ResponseBody注解实现json数据交互

Json数据在企业中使用好处:

Json在企业开发中已经作为通用的接口参数类型。

Json数据在页面(客户端)解析很方便。

 

Json定义:

var obj=name”:”张三”,”age”:12//key/value格式

Json数据解析:

obj.name


在处理器适配器上配置json的解析器,原因是处理器适配器处理handler

配置

<!--注解适配器 -->
	<!-- <bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		json转换器
		<property name="messageConverters">
			<list>
				<bean
					class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
			</list>
		</property>

	</bean> -->
controller层

/**
 * 
 * <p>Title: JsonAction</p>
 * <p>Description: json转换测试</p>
 * <p>Company: www.itcast.com</p> 
 * @author	传智.燕青
 * @date	2014-12-15下午5:38:43
 * @version 1.0
 */
@Controller
public class JsonAction {
	
	//请求json响应json
	@RequestMapping("/requestJson")
	public @ResponseBody Student requestJson(@RequestBody Student student)throws Exception{
		
		System.out.println(student);
		return student;
	}
	
	
	//请求key/value响应json
	@RequestMapping("/responseJson")
	public @ResponseBody Student responseJson(Student student)throws Exception{
		
		System.out.println(student);
		return student;
	}

}


9、springMVC的拦截器

 

拦截器是针对handlerMapping的拦截器,由handlerMapping查找Handler后,将拦截器返回给前端控制器(DispatcherServlet)。


间接配置全局拦截器:让springmvc框架自动向每个handlerMapping中注册拦截器

<!--拦截器 -->
	<mvc:interceptors>
		<!--多个拦截器,顺序执行 -->
		<!-- <mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="cn.itcast.springmvc.interceptor.HandlerInterceptor1"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="cn.itcast.springmvc.interceptor.HandlerInterceptor2"></bean>
		</mvc:interceptor> -->
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="cn.itcast.springmvc.interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
		
	</mvc:interceptors>

定义拦截器
实现HandlerInterceptor接口。

public class HandlerInterceptor1 implements HandlerInterceptor {

	//handler,springmvc根据url找到Handler(只有一个方法)
	//执行时机:进入Handler方法之前执行,如果返回false表示拦截,如果返回true表示放行
	//使用场景:用于用户身份校验,用户权限拦截校验
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		System.out.println("HandlerInterceptor1..preHandle");
		
		return false;
	}
	//执行时机:进入Handler方法之后 ,在返回modelAndView之前 
	//使用场景:使用modelAndView,向页面传递通用数据,使用统一的view
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("HandlerInterceptor1..postHandle");
		
	}
	//执行时机:Handler方法执行完成,(modelAndView已经返回)
	//使用场景:统一异常处理,统一记录系统日志,用于action方法执行监控(在preHandle记录一个时间点,在afterCompletion记录执行结束时间点,将结束时间点减去开始执行时间点,得到执行时长)
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("HandlerInterceptor1..afterCompletion");
		
	}


10、springmvc驱动



<!--注解映射器 -->
	<!-- <bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> -->
	<!--注解适配器 -->
	<!-- <bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		json转换器
		<property name="messageConverters">
			<list>
				<bean
					class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
			</list>
		</property>

	</bean> -->
	
	<!-- 使用<mvc:annotation-driven />替换上边定义的处理器映射器和适配器 并且默认是支持@RequestBody @ResponseBody这两个注解的--> 										<mvc:annotation-driven />
参考代码案例: 点击打开链接






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值