什么是springmvc,它与spring有什么关系
springmvc属于spring框架的后续产品,用在基于MVC的表现层开发,类似于struts2框架
Spring框架提供了一个构建Web应用程序的全功能MVC模块--Spring MVC。
Spring MVC具有如下特点:
Spring MVC拥有强大的灵活性、非侵入性和可配置性。
Spring MVC提供了一个前端控制器DispatcherServlet,开发者无需额外开发控制器对象。
Spring MVC分工明确,包括控制器,验证器,命令对象,模型对象,处理程序映射视图解析器等等,每一个功能实现由一个专门的对象负责完成。
Spring MVC可以自动绑定用户输入,并正确地转换数据类型。例如,Spring MVC能自动解析字符串,并将其设置为模型的int或float类型的属性。
Spring MVC使用一个名称/值的Map对象实现更加灵活的模型数据传输。
Spring MV内置了常见的校验器,可以校验用户输入,如果校验不通过,则重定向回输入表单。输入校验是可选的,并且支持编程方式及声明方式。
Spring MVC支持国际化,支持根据用户区域显示多国语言,并且国际化的配置非常简单。
Spring MV支持多种视图技术,最常见的JSP技术以及其他技术,包括Velocity和FreeMarker。
Spring提供了一个简单而强大的JSP标签库,支持数据绑定功能,使得编写JSP页面更加容易。
springmvc工作流程
Spring MVC请求→响应的完整工作流程如下:
(1) 用户向服务器发送请求,请求被Spring 的前端控制DispatcherServlet截获。
(2) DispatcherServlet对请求URL(统一资源定位符)进行解析,得到URI(请求资源标识符)。然后根据该URI,调用HandlerMapping(处理映射对象)获得该Handler配置的所有相关的对象,包括Handler对象以及Handler对象对应的拦截器,这些对象会被封装到一个HandlerExecutionChain对象当中返回。
(3) DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter(处理适配器对象)。HandlerAdapter的设计符合面向对象中的单一职责原则,代码架构清晰,便于维护,最重要的是代码可复用性高。HandlerAdapter会被用于处理多种Handler,调用Handler实际处理请求的方法,例如hello方法。
(4) 提取请求中的模型数据,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
消息转换: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
(5) Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象,ModelAndView对象中应该包含视图名或视图名和模型。
(6) 根据返回的ModelAndView对象,选择一个适合的ViewResolver(视图解析器)返回给DispatcherServlet。
(7) ViewResolver 结合Model和View,来渲染视图。
(8) 将视图渲染结果返回给客户端。
以上8个步骤,DispatcherServlet、HandlerMapping、HandlerAdapter和ViewResolver等对象协同工作,完成Spring MVC请求→响应的整个工作流程,这些对象所完成的工作对于开发者来说都是不可见的,开发者并不需要关心这个对象是如何工作的,开发者的只需要在Handler(Controller)当中完成对请求的业务处理。
代码示例:
新建一个动态的web工程
导入相关Jar包
写一个请求:index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="hello">提交请求</a> </body> </html>
配置web.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>基于注解的springmvc</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 定义springmvc前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-指定查找/WEB-INF/springmvc-config.xml 下的配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-config.xml</param-value> </init-param> <!-- 表示第一次加载 --> <load-on-startup>1</load-on-startup> </servlet> <!-- 让Spring MVC的前端控制器拦截所有请求 /表示所有的 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
注: web.xml中是标准Java EE Servlet的配置,配置了一个DispatcherServlet,该Servlet在web应用程序启动时立即加载,DispatcherServlet加载会时需要一个Spring MVC的配置文件,默认会去应用程序目录的WEB-INF下查找对应的[servlet- name]-servlet.xml文件,例如本例的<servlet-name>是springmvc,默认查找的就是/WEB-INF/springmvc-servlet.xml。
也可以把Spring MVC的配置文件放到应用程序目录中的任何地方,用servlet元素的init-param子元素进行描述,本例的param-name元素的值contextConfigLocation表示参数名称,param-value元素的值/WEB-INF/springmvc-config.xml则表示Spring MVC的配置文件路径和名称。则DispatcherServlet会查找/WEB-INF/springmvc-config.xml文件,作为Spring MVC的配置文件,解析该文件内容并根据文件配置信息创建一个WebApplicationContext容器对象,也称为上下文环境。
配置springmvc-config.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> <!-- 自动扫描该包,SpringMVC会将包下用了@controller注解的类注册为Spring的controller --> <context:component-scan base-package="org.fkjava.action"/> <mvc:annotation-driven/><!--spingmvc的注解驱动,表示自动注册,将bean加到工厂中 -->。 <!-- 默认访问静态 -->
<mvc:default-servlet-handler/> </beans>
创建HelloAction.java控制器
package org.fkjava.action; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller //表示一个控制器类 public class HelloAction { /**方式一 @RequestMapping(value="/hello") //对应映射路径 public String hello(Model model){ System.out.println("进入HelloAction的hello()方法"); //设置数据 model.addAttribute("userName", "jack"); return "/success.jsp"; } */方式二 @RequestMapping(value="/hello") //对应映射路径 public ModelAndView hello(ModelAndView mv){ System.out.println("进入HelloAction的hello()方法"); //设置数据 mv.addObject("userName", "tom"); mv.setViewName("/success.jsp"); return mv; } }
在/WebContext/下创建success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> userName:${requestScope.userName} </body> </html>
部署web应用到tomcat中,通过浏览器访问如下URL:
http://localhost:8080/springmvc01/index.jsp
springmvc与struts2的区别
1)springmvc的入口是一个servlet,即前端控制器,例如:*.action
struts2入口是一个filter过虑器,即前端过滤器,例如:/*
2)springmvc是基于方法开发,传递参数是通过方法形参,可以设计为单例
struts2是基于类开发,传递参数是通过类的属性,只能设计为多例
3)springmvc通过参数解析器是将request对象内容进行解析成方法形参,将响应数据和页面封装成
ModelAndView对象,最后又将模型数据通过request对象传输到页面
struts采用值栈存储请求和响应的数据,通过OGNL存取数据
常用注解:
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象,即一个控制器类。Spring使用扫描机制查找应用程序中所有基于注解的控制器类。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。为了保证Spring能找到控制器,需要完成两件事情。
(1) 在Spring MVC的配置文件中头文件引入spring-context。
(2) 使用<context:component-scan/>元素,该元素的功能为:启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean。base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
配置文件如下所示:
<context:component-scan base-package="org.fkit.controller"/>
应该将所有控制器类都放在基本包下,并且指定扫描该包,即org.fkit.controller,而不应该指定扫描org.fkit包,以免Spring MVC扫描了无关的包。
@RequestMapping注解类型指示Spring用哪一个方法来处理请求动作,该注解可用于类或方法上。
WebRequest是Spring Web MVC提供的统一请求访问接口,不仅仅可以访问请求相关数据(如参数区数据、请求头数据,但访问不到Cookie区数据),还可以访问会话和上下文中的数据;NativeWebRequest继承了WebRequest,并提供访问本地Servlet API的方法。
(1) webRequest.getParameter:访问请求参数区的数据,可以通过getHeader()访问请求头数据;
(2) webRequest.setAttribute/getAttribute:到指定的作用范围内取/放属性数据,Servlet定义的三个作用范围分别使用如下常量代表:
SCOPE_REQUEST :代表请求作用范围;
SCOPE_SESSION :代表会话作用范围;
SCOPE_GLOBAL_SESSION :代表全局会话作用范围,即ServletContext上下文作用范围。 (global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。
(3) nativeWebRequest.getNativeRequest/nativeWebRequest.getNativeResponse:得到本地的Servlet API。
Mode对象
Spring MVC在调用处理方法之前会创建一个隐含的模型对象,作为模型数据的存储容器。如果处理方法的参数为Model类型,Spring MVC会将隐含模型的引用传递给这些参数。在处理方法内部,开发者就可以通过这个参数对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
在处理方法中Mode对象可以使用如下方法添加模型数据:
addObject(String attributeName,Object attributeValue);
如: @RequestMapping(value="/main") public String main(Model model){ // 获得所有图书集合 List<Book> book_list = bookService.getAll(); // 将图书集合添加到model当中 model.addAttribute("book_list", book_list); // 跳转到main页面 return "main"; }
ModelAndView,则即包含模型数据信息,也包含视图信息,可以简单的将模型数据看成一个Map<String,Object>对象。
在处理方法中可以使用ModeAndView对象的如下方法添加模型数据:
addObject(String attributeName,Object attributeValue);
可以通过如下方法设置视图:
setViewName(String viewName):指定一个逻辑视图名。
注意:设置到Model中的数据一定会设置到request对象当中。
但是如果数据是设置到ModelAndView当中,而ModelAndView没有返回,则没有数据。
@RequestParam注解用于将指定的请求参数赋值给方法中形参。
如果设置该注解,则参数必须传递。
如:
@RequestMapping(value="/login") public ModelAndView login( @RequestParam("loginname") String loginname, @RequestParam("password") String password){ return ……; }
@PathVariable注解可以非常方便的获得请求url中的动态参数。
@PathVariable注解只支持一个属性value,类型为String,表示绑定的名称,如果省略则默认绑定同名参数。示例代码如下:
@RequestMapping(value="/pathVariableTest/{userId}")
public void pathVariableTest(@PathVariable Integer userId)
假如请求的URL为“http://localhost:8080/testapp/pathVariableTest/1”,则自动将URL中模板变量{userId}绑定到通过@PathVariable注解的同名参数上,即userId变量将被被赋值为1。
<td><a href="remove.action/${book.id }">删除</a></td>
@RequestMapping(value="/remove.action/{bookId}")
public ModelAndView remove(@PathVariable Integer bookId,ModelAndView mv){
System.out.println("BookAction:remove --> " + bookId);
service.removeBookById(bookId);
mv.setViewName("redirect:/getAllBook.action");
return mv;
}
spring常用注解
为Spring的Bean增加注解。
@Component|@Controller|@Service|@Repository:标注一个普通的Spring Bean类。 <bean .../>元素
这些注解,如果不指定id,默认该Bean的id就是其类名的首字母小写
@Controller:标注一个控制器组件类。
@Service:标注一个业务逻辑组件类。
@Repository:标注一个DAO组件类。 XxxRepository
@Autowired与@Qualifier:自动装配。@Autowired默认是byType的自动装配。
@Qualifier可指定byName的自动装配。
@Transactional 配置事务