SpringMVC入门

SpringMVC入门

1. SpringMVC简介

在之前,我们曾学过基于MVC思想的struts2框架,而Spring本身对于Web开发也提供了一个非常强大的解决方案。SpringMVC基于模型-视图-控制器(Model-View-Controller,MVC)模式实现,它能够帮助我们构建更为灵活和松耦合的Web应用程序。

SpringMVC得益于自身两大核心技术DI和AOP的运用,使得我们可以在Web项目中以更优雅和更健壮的方式引入、整合各类资源。目前,SpringMVC在Web框架的市场份额上,已经遥遥领先于struts2等传统Web框架。

2. 搭建SpringMVC

2.1 引入类库

要使用SpringMVC,需要首先新建基于“war”的maven项目,在pom.xml中引入spring-webmvc模块:

<modelVersion>4.0.0</modelVersion>
<groupId>com.turing</groupId>
<artifactId>spring-06</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.19.RELEASE</version>
    </dependency>
</dependencies>

打开pom的树状依赖视图

在这里插入图片描述

我们可以看到spring-webmvc模块把我们需要用到的spring其它相关模块(数据访问类模块除外)都引入进来了。

2.2 配置DispatcherServlet

类似于struts2的配置,我们同样需要在web应用中注册SpringMVC的前端控制器。与struts2不同的是,SpringMVC的前端控制器不是基于Filter的,而是基于Servlet(DispatcherServlet)的。

我们可以像struts2一样,在web.xml中对SpringMVC的前端控制器进行配置,但为了结合Servlet3.0+的新特性,同时为了更便利的使用Spring后续的新功能,我们将使用基于Java的配置来对SpringMVC的前端控制器进行注册。在编写这些配置之前,让我们先来了解一下Servlet3.0+以及SpringMVC中与Servlet配置有关的一些新特点:

在这里插入图片描述

Servlet3.0+环境中,容器会在类路径中查找实现了javax.servlet.ServletContainerInitializer接口的类,如果能发现的话,就会用它来配置Servlet。

而Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类会反过来查找实现了WebApplicationInitializer的类并将配置的任务交给它们来完成。为了更简便的实现WebApplicationInitializer接口,Spring提供了一个抽象类,我们只需要继承这个抽象类,就能完成对DispatcherServlet的注册。

public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override // 获得根配置类
	protected Class<?>[] getRootConfigClasses() {
		return new Class<?>[] { RootConfig.class };
	}

	@Override // 获得web配置类
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[] { WebConfig.class };
	}

	@Override // 配置servlet-mapping
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}

}

忽略getRootConfigClasses()getServletConfigClasses(),以上配置和web.xml中的这段配置,效果是等价的:

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

接下来,让我们再来看看接下来的两个方法做了什么。

2.3 应用上下文配置

2.3.1 DispatcherServlet上下文

当DispatcherServlet加载以后,它会创建Spring应用上下文,并加载配置文件或者配置类中所声明的bean。让我们看看WebConfig这个配置类到底做了哪些工作:

@Configuration
@EnableWebMvc // 启用SpringMVC
@ComponentScan("com.turing.web")
public class WebConfig extends WebMvcConfigurerAdapter {

	@Bean
	public ViewResolver viewResolver() {
		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
		// 设置视图前缀
		resolver.setPrefix("/");
		// 设置视图后缀
		resolver.setSuffix(".jsp");
		// 让上下文的bean在请求的属性中也可以访问
		resolver.setExposeContextBeansAsAttributes(true);
		return resolver;
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		// 配置静态资源的处理
		configurer.enable();
	}

}
  • 首先通过@EnableWebMvc启动SpringMVC
  • @ComponentScan("com.turing.web")用来配置DispatcherServlet所启动的上下文中所应包含的bean,这些bean主要是Controller(类似struts2中的action)、用户自定义的servlet、filter、listener以及视图解析器等。
  • viewResolver()主要用来生成视图解析器,SpringMVC的controller中的用来处理请求的方法和struts2类似,也是返回String类型的结果,我们只需要给InternalResourceViewResolver设置相应的前缀和后缀。例如,如果处理请求的方法返回的是“success”,那spring根据视图解析器找到的页面路径将会是“/success.jsp”。
  • 最后,我们通过重写configureDefaultServletHandling()方法,使得图片、样式等静态资源不经由DispatcherServlet处理。
2.3.2 ContextLoaderListener上下文

在Spring Web应用中,通常还会有另外也给上下文。这个上下文是由ContextLoaderListener创建的。这个上下文主要用来加载应用中除开web组件以外其他的bean,比如service、dao等。

@Configuration
@ComponentScan(basePackages = { "com.turing" }, excludeFilters = {
		@Filter(type = FilterType.ANNOTATION, value = { EnableWebMvc.class, Controller.class }) })
public class RootConfig {

}

excludeFilters中,我们对类上标记了@EnableWebMvc@Controller的类不进行扫描,以面重复装载Bean到Spring容器中。

为了便于更好的理解两个上下文之间的关系,我们来看一下项目的包结构:

在这里插入图片描述

2.4 编写控制器

@Controller
public class HelloController {

	private final Logger logger = LogManager.getLogger(HelloController.class);

	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String hello(Model model) {
		model.addAttribute("username", "jack");
		logger.debug("HelloController:hello()");
		return "success";
	}

}
  • @Controller该注解用来声明spring的控制器,本身与@Component没有区别,只不过是用来表示控制器的身份而已,让开发者看起来更清晰。
  • @RequestMapping用来声明访问路径与处理方法/类的映射关系

3. SpringMVC的请求处理流程

通过上面这个简单的hello案例,我们一起来回顾一下SpringMVC的执行流程:

在这里插入图片描述

  1. 当我们输入“/hello”时,请求的第一站是DispatcherServlet这个前端控制器,它的任务是根据处理器映射来选择合适的controller。
  2. controller中我们已经将路径与处理方法的对应关系,通过@RequestMapping注册到了上下文中的处理器映射中。
  3. 通过查询处理器映射,DispatcherServlet会将请求派发给HelloController.hello(),并等候处理结果
  4. hello方法处理完成后,会将模型数据打包(model),并标识出要展示的视图逻辑名称(“success”)
  5. 前端控制器DispatcherServlet通过我们之前配置的视图解析器InternalResourceViewResolver,给视图名添加对应的前缀和后缀,最终得到完整的视图路径(”/success.jsp“)。
  6. 结合处理请求得到的模型数据model和动态页面”/success.jsp“,渲染输出好视图。
  7. 最终将这个视图页面以html格式返回给前端。

4.使用log4j2记录日志

在SpringMVC中使用log4j2记录日志也是非常方便的,不过与mybatis不同的是,除开引入Log4j的类库外,还需要额外引入Log4j JCL的库:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jcl</artifactId>
    <version>2.11.1</version>
</dependency>

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
	<Appenders>
		<Console name="STDOUT" target="SYSTEM_OUT">
			<PatternLayout pattern="%-5p [%C{2}] (%F:%L) - %m%n" />
		</Console>
	</Appenders>
	<Loggers>
		<!-- <Logger name="org.springframework.beans.factory" level="DEBUG" /> -->
		<Root level="debug">
			<AppenderRef ref="STDOUT" />
		</Root>
	</Loggers>
</Configuration>
</Appenders>
<Loggers>
	<!-- <Logger name="org.springframework.beans.factory" level="DEBUG" /> -->
	<Root level="debug">
		<AppenderRef ref="STDOUT" />
	</Root>
</Loggers>
```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值