springmvc(一)

什么是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

 

springmvcstruts2的区别

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 配置事务

posted @ 2017-02-28 00:39  kinglone  阅读(503)  评论(0编辑  收藏  举报