SpringMVC入门------简介,工作流程,适配器模式,注解

目录

  1. spring MVC简介
  2. Spring MVC工作流程
  3. Spring MVC适配器模式
  4. Spring MVC注解
  5. json消息转发器

一、Spring MVC简介

Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架。与Struts2框架一样,都属于MVC框架,但其使用和性能等方面比Struts2更加优异。
MVC框架主要处理的问题是如何接收请求以及如何响应请求;

特点:
1)是Spring框架的一部分,可以方便的利用Spring所提供的其他功能;
2)灵活性强,易于与其他框架集成;
3)提供了一个前端控制器DispatcherServlet,使开发人员无需额外开发控制器对象;
4)可自动绑定用户输入,并能正确的转换数据类型;
5)内置了常见的校验器,可以教研用户输入。如果校验不通过,就会重定向到输入表单;
6)支持国际化。可以根据用户区域显示躲过语言;
7)支持多种模板引擎:JSP,beetl,FreeMarker,Velocity等;
8)使用基于XML的配置文件,在编辑后,不需要重新编译应用程序。

二、Spring MVC工作流程:

在这里插入图片描述
① 用户通过浏览器向服务器发送请求,请求会被Spring MVC的前端控制器DispatcherServlet拦截;

② DispatcherServlet拦截到请求后,会调用HandlerMapping处理器映射器;

③ 处理器映射器根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;

④ DispatcherServlet会通过返回信息选择合适的HandlerAdapter(处理器适配器);

⑤ HandlerAdapter会调用并执行Handler(处理器),这里的处理器值得就是程序中编写的Controller类,也被称为后端控制器;

⑥ Controller执行完后,会返回一个ModelAndView对象,该对象中会包含视图名或包含模型和视图名;

⑦ HandlerAdapter将ModelAndView对象返回给DispatcherServlet;

⑧ DispatcherServlet会根据ModelAndView对象选择一个合适的ViewReslover(视图解析器);

⑨ ViewReslover解析后,会向DispatcherServlet中返回具体的View(视图);

⑩DispatcherServlet对View进行渲染(即将模型数据填充至视图中);视图渲染的结果会返回给客户端浏览器显示

Spring核心包和Spring MVC核心包:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.1.6.RELEASE</version>
		</dependency>
		
		<!--  Spring MVC 包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

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

<web-app>
  <servlet>
    <!--配置前端控制器对访问进行拦截-->
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>//类路径下的配置文件
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

三、Spring MVC----适配器模式

好处:

代码发布之后如果要增加新的组件或者标准,用户可根据需求来写,只要添加一个组件和它对应的适配器即可,标准在adapter适配器中,从而使标准和实现进行解耦了。用户写一个类,加上他所需的适配器,告诉Tomcat怎么运行,自己写handle,就不用遵循http组件的标准了。只需遵循自己的适配器标准即可,先走什么,再走什么方法,都是由自己handle

首先了解下分别使用bean name方式(HttpHandlerAdapter)简单映射方式(SimpleHandlerAdapter)注解方式(AnnotationHandlerAdapter)实现适配器模式的总结构:

在这里插入图片描述
1)创建组件和适配器的接口

public interface MockController {
	
}

/*
 * Spring MVC的适配器模式
 */
public interface MockAdapter {
	
	//传入一个类,判断当前类是否能被适配器适配
	public boolean support(Object handler);
	
	//如果当前适配器能适配,则调用该方法处理,,handle处理,handler当前被处理的对象
	public void handle(Object handler);
}

2)三大实现方式的Controller组件:

/*
 * Spring MVC的适配器模式,通过bean name实现的Controller组件
 * 
 * 要让组件能够工作,必须添加能让其工作的适配器:HttpHandleAdapter即http处理适配器
 */
public class HttpController implements MockController{

	public void doHttpController() {
		// TODO Auto-generated method stub
		System.out.println("HttpController");
	}
}


/*
 * Spring MVC的适配器模式,通过simple简单映射方式实现
 */
public class SimpleController implements MockController{
	public void doSimpleController() {
		System.out.println("SimpleController");
	}
}


/*
 * Spring MVC的适配器模式,通过注解方式实现
 */
public class AnnotationController implements MockController{

	public void doAnnotationController() {
		System.out.println("AnnotationController");
	}
}

3)编写三种实现方式的适配器及实现其标准

support方法:传入一个类对象,判断当前类是否能被适配器适配

handle方法:如果当前适配器能适配,则调用该方法处理,handle处理,handler当前被处理的对象

HttpHandleAdapter .java

/*
 * 实现适配器接口,适配器和控制器都是由用户提供的
 */
public class HttpHandleAdapter implements MockAdapter{
	
	//处理 bean name方式的handler
	public boolean support(Object handler) {
		
		//如果传进来的是HttpController的子类
		if(handler instanceof HttpController) {
			return true;
		}
		return false;
	}

	//经过support方法的逻辑确认是HttpController的子类,所以可以直接进行强转
	public void handle(Object handler) {
	
		HttpController httpController = (HttpController) handler;
		httpController.doHttpController();
	}
}

SimpleHandlerAdapter.java 和 AnnotationHandlerAdapter.java 实现与上基本一致,略过。。。

4)模拟Spring MVC框架的DispatcherServlet前端控制器:

/*
 * 框架源码,模拟spring MVC的DispatcherServlet,将其核心逻辑取出来
 */

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

public class MockDispatcherServlet {
	
	//集合中收集了所有Adapter的实现,spring收集所有存在的adapter然后通过@Autowired自动注入
	//但此时没有spring所以重写构造器,将所有adapter创建出来
	private List<MockAdapter> adapters= new ArrayList<MockAdapter>();
	
	//构造方法
	public MockDispatcherServlet() {
		adapters.add(new HttpHandleAdapter());
		adapters.add(new SimpleHandleAdapter());
		adapters.add(new AnnotationHandleAdapter());
	}
	
	public static void main(String[] args) {
		new MockDispatcherServlet().doService();
	}

	public void doService() {
		AnnotationController annoController = new AnnotationController();
		//HttpController httpHontroller = new HttpController();
		//SimpleController simpleHontroller = new SimpleController();

		//遍历所有的适配器
		for (MockAdapter mockAdapter : adapters) {
			//如果当前用户请求支持
			if (mockAdapter.support(annoController)) {
				//执行相应的方法
				mockAdapter.handle(annoController);//AnnotationController
			}
		}
	}
}

四、注解方式

1.在applicationContext-mvc.xml文件中加上约束:

在namespaces中勾选 context 和 mvc
在这里插入图片描述2.开启注解

	<!-- 开启springMVC注解支持 -->
	<mvc:annotation-driven></mvc:annotation-driven>
	
	<!-- 开启默认的对静态资源文件访问的支持 -->
	<mvc:default-servlet-handler />
	
	<!-- 开启对于Spring 组件扫描的支持 spring容器中,只注册controller注解 -->
	<context:component-scan base-package="net.xikee">
		<context:include-filter type="annotation"	//表示注解
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

注:为避免和spring配置文件applicationContext.xml文件扫描到同样的组件,产生两个相同的bean,此处需要配置一个过滤器 include-filter,只扫描包含Controller的组件
然后在applicationContext.xml文件中设置exclude-filter:

<!-- 开启对于Spring 组件扫描的支持 spring容器中,只注册除controller外的注解 -->
	<context:component-scan base-package="net.xikee">
		<context:exclude-filter type="annotation"	//表示注解
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

3.测试:

@Controller
@RequestMapping("/hello")
public class HelloController {

	@RequestMapping("/1")
	public String SayHello() {
		System.out.println("hello controller");
		return "hello.jsp";
	}

@RequestMapping("/hello")注解表示当前类的所有方法有个共有的头,加上@RequestMapping("/1")注解表示当前方法访问路径是:/hello/1
此时通过requestMapping分发请求,而不像以前需要判断用户请求,然后通过switch进行分发

五、Spring MVC的 消息转发器中 json 与对象之间的转换

导入jackson所需的 jar 包:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>${jackson.version}</version>
		</dependency>

applicationContext-mvc.xml文件中的配置:

<!-- Spring MVC中的请求映射处理适配器 -->
	<bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="messageConverters"><!-- 消息转发器:json转对象&&对象转json -->
			<!-- jackson是spring支持json消息转发器的底层实现 -->
			<bean
				class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
		</property>
	</bean>

restful风格

在测试类HelloController类 (@RequestMapping("/hello"))中:

未加@ResponseBody之前,浏览器访问 /hello/3这个接口会报404,浏览器不知道返回的users类型是什么

加上@ResponseBody之后,浏览器访问接口会返回20个json形式的数据

	@ResponseBody
	@RequestMapping("/3")
	public List<User> queryAllUser(){
		List<User> users = new ArrayList<User>();
		for(int i=0; i<20; i++) {
			users.add(new User(i, "xikee"+i, "123456", 10d));
		}
		return users;
	}

如果在类上面加上@RestController,除有@Controller功能外,还相当于在每个方法上加上@ResponseBody

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值