SpringMVC基础知识(1)

本文详细介绍了SpringMVC框架的工作原理及其组成部分,包括前端控制器、处理器映射器、适配器等,并通过实例展示了如何搭建SpringMVC环境,实现商品列表查询的功能。

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

1、SpringMVC框架

1.1、什么是SpringMVC?

      SpringMVC是Spring框架的一个模块,SpringMVC和Spring无需通过中间整合层进行整合。

      SpringMVC是一个基于mvc的web层框架。

1.2、mvc在b/s系统下的应用

      mvc是一种设计模式,mvc在b/s系统下的应用如下图:


1.3、SpringMVC框架

      原理图:


      执行步骤:

      第一步:发起请求到前端控制器(DispatcherServlet)

      第二步:前端控制器请求处理器映射器(HandlerMapping)查找Handler,可以根据xml配置、注解进行查找。

      第三步:处理器映射器(HandlerMapping)向前端控制器返回Handler(一个包含Handler的执行链)。

      第四步:前端控制器调用处理器适配器去执行Handler

      第五步:处理器适配器去执行Handler

      第六步:Handler执行完成后给处理器适配器返回ModelAndView

      第七步:处理器适配器向前端控制器返回ModelAndView(SpringMVC的一个底层对象,包括Model和View)

      第八步:前端控制器请求视图解析器(ViewResolver)去进行视图解析(根据逻辑视图名解析成真正的物理视图(jsp))

      第九步:视图解析器向前段控制器返回View

      第十步:前端控制器进行试图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域

      第十一步:前端控制器向用户响应结果


      组件:

      1、前端控制器DispatcherServlet(不需要程序员开发)

      作用:接收请求、响应结果,相当于转发器,中央处理器。DispatcherServlet减少了其它组件之间的耦合度。

      2、处理器映射器HandlerMapping(不需要程序员开发)

      作用:根据请求的url查找Handler

      3、处理器适配器HandlerAdapter

      作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler

      4、处理器Handler(需要程序员开发)

      注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler

      5、视图解析器ViewResolver(不需要程序员开发)

      作用:进行视图解析,根据逻辑视图名解析成真正的视图

      6、视图View(需要程序员开发jsp)

      View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf……)


2、入门程序

2.1、需求

      商品订单管理

      功能需求:商品列表查询

2.2、环境准备

      springmvc版本:spring3.2

      需要spring3.2所有jar包(一定包括spring-webmvc-3.2.0.RELEASE.jar)


2.3、配置前端控制器

      在web.xml中配置前端控制器

 <!-- SpringMVC前端控制器 -->
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<!-- 
  		contextConfigLocation配置SpringMVC加載的配置文件(配置处理器映射器、适配器等)
  		如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlert名称-servlet.xml(springmvc-servlet.xml)
  	 -->
  	 <init-param>
  	 	<param-name>contextConfigLocation</param-name>
  	 	<param-value>classpath:springmvc.xml</param-value>
  	 </init-param>
  </servlet>
  
  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<!-- 
  		第一种:*.action,访问以.action结尾,由DispatcherServlet进行解析
  		第二种:/,所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析,
  		             使用此种方式可以实现RESTful风格的url
  		第三种:/*,这样配置不对,使用这种方式配置,最终要转发到一个jsp页面,仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。
  	 -->
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>
2.4、配置处理器适配器

      在classpath下的springmvc.xml中配置处理器适配器

<span style="white-space:pre">	</span><!-- 
		处理器适配器:
		所有的处理器适配器都实现HandlerAdapter接口
	 -->
	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
      通过查看源代码:


      此适配器能执行实现Controller接口的Handler。


2.5、开发Handler

      需要实现Controller,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter适配器执行。

package lsq.ssm.controller;

import java.util.ArrayList;
import java.util.List;

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

import lsq.ssm.po.Items;

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

/**
 * 实现Controller接口的处理器
 * @author Daniel Li
 *
 */
public class ItemsController1 implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		//调用service查找数据库,查询商品列表,这里使用静态数据模拟
		List<Items> itemsList = new ArrayList<Items>();
		
		//向itemsList中填充静态数据
		Items items_1 = new Items();
		items_1.setName("联想笔记本");
		items_1.setPrice(6000f);
		items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
		
		Items items_2 = new Items();
		items_2.setName("苹果手机");
		items_2.setPrice(5000f);
		items_2.setDetail("iphone6苹果手机!");
		
		itemsList.add(items_1);
		itemsList.add(items_2);
		
		//返回ModelAndView
		ModelAndView modelAndView = new ModelAndView();
		//相当于request的setAttribute(),在jsp页面中通过itemsList获取数据
		modelAndView.addObject("itemsList", itemsList);
		
		//指定视图
		modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
		
		return modelAndView;
	}

}
2.6、视图编写

   
2.7、配置Handler

      为了编写的Handler能够在spring容器中加载。

	<!-- 配置Handler -->
	<bean name="/queryItems.action" class="lsq.ssm.controller.ItemsController1"/>
2.8、配置处理器映射器

      在classpath下的springmvc.xml中配置处理器映射器

	<!-- 
		处理器映射器:
		将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)
		所有的映射器都实现HandlerMapping接口
	 -->
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
2.9、配置视图解析器

      需要配置解析jsp的视图解析器

	<!-- 
		视图解析器:
		解析jsp视图,默认使用jstl标签,classpath下要有jstl的包
	 -->
	 <bean	class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
2.10、部署调试

      访问地址:http://localhost:8080/springmvc_day1/queryItems.action


2.11、两种常见错误

      处理器映射器根据url找不到Handler,报下边的错误。说明url错误。


      处理器映射器根据url找到了Handler,转发的jsp页面找不到,报下边的错误,说明jsp页面地址写错了。


3、非注解的处理器映射器和处理器适配器

3.1、非注解的处理器映射器

      处理器映射器:

      org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping

      另一个映射器:

      org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

	<!-- 简单url映射 -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<!-- 对itemsController1进行url映射,url是/queryItems1.action -->
				<prop key="/queryItems1.action">itemController1</prop>
				<prop key="/queryItems2.action">itemController1</prop>
			</props>
		</property>
	</bean>
      修改Handler配置,添加id属性:

	<!-- 配置Handler -->
	<bean id="itemController1" name="/queryItems.action" class="lsq.ssm.controller.ItemsController1"/>
      ☆结论:多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。

3.2、非注解的处理器适配器

      第一种:

      org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter

      要求编写的Handler实现Controller接口。

      第二种:

      org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter

      要求编写的Handler实现HttpRequestHandler接口。

package lsq.ssm.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

import lsq.ssm.po.Items;

import org.springframework.web.HttpRequestHandler;

/**
 * 实现HttpRequestHander接口的处理器
 * @author Daniel Li
 *
 */
public class ItemsController2 implements HttpRequestHandler{

	@Override
	public void handleRequest(HttpServletRequest request, HttpServletResponse resposne)
			throws ServletException, IOException {
				//调用service查找 数据库,查询商品列表,这里使用静态数据模拟
				List<Items> itemsList = new ArrayList<Items>();
				//向list中填充静态数据
				
				Items items_1 = new Items();
				items_1.setName("联想笔记本");
				items_1.setPrice(6000f);
				items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
				
				Items items_2 = new Items();
				items_2.setName("苹果手机");
				items_2.setPrice(5000f);
				items_2.setDetail("iphone6苹果手机!");
				
				itemsList.add(items_1);
				itemsList.add(items_2);
				
				//设置模型数据
				request.setAttribute("itemsList", itemsList);
				//设置转发的视图
				request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, resposne);
				
				//使用此方法可以通过修改response,设置响应的数据格式,比如响应json数据
				/*response.setCharacterEncoding("utf-8");
				response.setContentType("application/json;charset=utf-8");
				response.getWriter().write("json串");*/
	}

}
      配置Handler:

	<!-- 配置另一个Handler -->
	<bean  id="itemController2" class="lsq.ssm.controller.ItemsController2"/>
      配置处理器映射器:

	<!-- 另一个非注解的适配器HttpRequestHandlerAdapter -->
	<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>


4、DispatcherServlet.properties

      DispatcherServlet.properties文件中的内容如下:


      前端控制器从上边的文件中加载处理器映射器、适配器、视图解析器等组件,如果不在springmvc.xml中进行配置,就使用默认加载的。

5、注解的处理器映射器和适配器

      在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。

      在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。

      在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。

      在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。

5.1、配置注解映射器和适配器

	<!--注解映射器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
	<!--注解适配器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
	
	<!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置
	mvc:annotation-driven默认加载很多的参数绑定方法,
	比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
	实际开发时使用mvc:annotation-driven
	 -->
	<!-- <mvc:annotation-driven></mvc:annotation-driven> -->
5.2、开发注解Handler

      使用注解的映射器和注解的适配器。(☆:注解的映射器和注解的适配器必须配对使用)

package lsq.ssm.controller;

import java.util.ArrayList;
import java.util.List;

import lsq.ssm.po.Items;

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

/**
 * 注解开发的Handler
 * @author Daniel Li
 *
 */
//使用Controller标识 它是一个控制器
@Controller
public class ItemsController3 {
		//商品查询列表
		//@RequestMapping实现 对queryItems方法和url进行映射,一个方法对应一个url
		//一般建议将url和方法写成一样
		@RequestMapping("/queryItems")
		public ModelAndView queryItems()throws Exception{
			
			//调用service查找 数据库,查询商品列表,这里使用静态数据模拟
			List<Items> itemsList = new ArrayList<Items>();
			//向list中填充静态数据
			
			Items items_1 = new Items();
			items_1.setName("联想笔记本");
			items_1.setPrice(6000f);
			items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
			
			Items items_2 = new Items();
			items_2.setName("苹果手机");
			items_2.setPrice(5000f);
			items_2.setDetail("iphone6苹果手机!");
			
			itemsList.add(items_1);
			itemsList.add(items_2);
			
			//返回ModelAndView
			ModelAndView modelAndView =  new ModelAndView();
			//相当 于request的setAttribut,在jsp页面中通过itemsList取数据
			modelAndView.addObject("itemsList", itemsList);
			
			//指定视图
			modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
			
			return modelAndView;
			
		}
}
5.3、在spring容器中加载Handler

	<!-- 对于注解的Handler可以单个配置
			实际开发中建议使用组件扫描
	 -->
	<!-- <bean class="lsq.ssm.controller.ItemsController3" /> -->
	<!-- 可以扫描controller、service、...
			这里让扫描controller,指定controller的包
	 -->
	<context:component-scan base-package="lsq.ssm.controller"></context:component-scan>
5.4、部署调试

      访问:http://localhost:8080/springmvc_day1/queryItems.action

6、源码分析
      通过前端控制器源码分析SpringMVC的执行流程。

      第一步:前端控制器接收请求

      调用doDispatch


      第二步:前端控制器调用处理器映射器查找Handler

      点击该方法进去:

      第三步:调用处理器适配器执行Handler,得到执行结果ModelAndView


      第四步:视图渲染,将model数据填充到request域。

      视图解析,得到view:


      点击render方法进去:


      调用view的渲染方法,将model数据填充到request域:

      渲染方法:


      将model数据填充到request域:







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值