Java拾遗之Spring Web MVc

Java拾遗之Spring Web MVc


Spring Web MVC 简介

MVC简介

M-Model模型

模型(Model)的职责是负责业务逻辑。包含两层:业务数据和业务处理逻辑。比如实体类、DAO、Service都属于模型层。

V-View视图

视图(View)的职责是负责显示界面和用户交互(收集用户信息)。属于视图的组件是不包含业务逻辑和控制逻辑的JSP。

C-Controller 控制器

控制器是模型层M和视图层V之间的桥梁,用于控制流程比如:在Servlet项目中的单一控制器ActionServlet。

什么是Spring Web MVC

Spring web MVC是Spring框架一个非常重要的功能模块。实现了MVC结构,便简单、快速开发MVC结构的Web程序。 Spring web MVC 提供的API封装了Web开发中常用的功能, 简化了Web过程。

Spring Web MVC的核心组件

Spring Web MVC提供了M、V和C相关的主要实现组件,具体如下
1. DispatcherServlet (控制器, 请求入口)
2. HandlerMapping (控制器, 请求派发)
3. Controller (控制器, 请求处理流程)
4. ModelAndView (模型, 封装业务处理结果和视图)
5. ViewResolver(视图, 视图显示处理器)

Spring Web MVC的处理流程

  1. 浏览器向Spring发出请求,请求交给前端控制器DispatcherServlet处理控制器通过HandlerMapping找到相应的Controller组件处理请求
  2. 执行Controller组件约定方法处理请求,在约定方法调用模型组件完成业务处理。约定方法可以返回一个ModelAndView对象,封装了处理结果数据和视图名称信息
  3. 控制器接收ModelAndView之后,调用ViewResolver组件,定位View(JSP)并传递数据信息,生成响应界面结果

基于XML配置的MVC应用

搭建Spring Web MVC环境

搭建Spring Web MVC开发环境的主要步骤如下
1. 创建Web工程,导入Spring Web MVC相关开发包(Spring API、web、webmvc等开发包)
2. 在src下添加Spring 的XML配置文件(名称可以自定义,例如spring-mvc.xml)
3. 在web.xml中配置DispatcherServlet前端控制器组件(1.DispatcherServlet组件在spring mvc中已提供,只需要配置即可、2.配置DispatcherServlet时,同时指定XML配置文件)

DispacherServlet控制器配置

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
             org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.form</url-pattern>
</servlet-mapping>

HandlerMapping组件

通过HandlerMapping组件,DispatcherServlet控制器可以将客户HTTP请求映射到Controller组件上。

SimpleUrlHandlerMapping

维护一个HTTP请求和Controller映射关系列表(map),根据列表对应关系调用Controller

SimpleUrlHandlerMapping使用定义如下

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
         <property name="mappings">
              <props>
                   <prop key="/login.form">loginController</prop>
                   <prop key="/hello.form">helloController</prop>
              </props>
         </property>
 </bean>

<bean id="helloController" class="org.tarena.web.HelloController"/>

RequestMappingHandlerMapping

RequestMappingHandlerAdapter

在Controller类和方法上使用@RequestMapping注解指定对应的客户HTTP请求(后续注解配置部分将详细介绍)

Controller组件

Controller组件负责执行具体的业务处理,可调用DAO等组件,编写时需要实现Controller接口及约定方法

public class HelloController implements Controller{

    public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
        System.out.println("Hello Spring!");
        return new ModelAndView("hello");
     }
}

ModelAndView组件

Controller组件约定的handleRequest方法执行后返回一个ModelAndView对象,该对象可封装模型数据和视图名响应信息。ModelAndView构造器如下
ModelAndView(String viewName)
ModelAndView(String viewName, Map model)

viewName是jsp页面的名字model 的数据存储到request的attribute中

ViewResolver组件

所有Controller组件都返回一个ModelAndView实例,封装了视图名。Spring中的视图以名字为标识,视图解析器ViewResolver通过名字来解析视图。
Spring提供了多种视图解析器,具体如下

ViewResolver组件 功能描述
UrlBasedViewResolver 将视图名直接解析成对应的URL,不需要显式的映射定义。如果你的视图名和视图资源的名字是一致的,就可使用该解析器,而无需进行映射
InternalResourceViewResolver UrlBasedViewResolver的子类, 它支持InternalResourceView(对Servlet和JSP的包装),以及其子类JstlView和TilesView响应类型
XmlViewResolver 支持用xml文件定义具体的响应视图文件
VelocityViewResolver / FreeMarkerViewResolver UrlBasedViewResolver的子类,它能支持Velocity和FreeMarker等视图技术

InternalResourceViewResolver使用示例如下

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/> 
    <property name="suffix" value=".jsp"/> 
</bean> 

如: 视图名hello 通过以上配置可以映射到/WEB-INF/jsp/hello.jsp

基于注解配置的MVC应用

RequestMapping注解应用

@RequestMapping可以用在类定义和方法定义上
@RequestMapping标明这个类或方法与哪一个客户请求对应

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

    @RequestMapping("/hello.form")
    public String execute() throws Exception {
        return "hello";
    }

}

开启@RequestMapping注解映射,需要在Spring的XML配置文件中定义RequestMappingHandlerMapping(类定义前)和RequestMappingHandlerAdapter(方法定义前)两个bean组件

**提示:Spring 3.1版本之前需要定义DefaultAnnotationHandlerMapping和
AnnotationMethodHandlerAdapter两个组件**

RequestMappingHandlerMapping和RequestMappingHandlerAdapter两个bean组件定义示例

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

**从Spring 3.2版本开始可以使用下面XML配置简化RequestMappingHandlerMapping和RequestMappingHandlerAdapter定义
<mvc:annotation-driven/>**

Controller注解应用

推荐使用@Controller注解声明Controller组件,这样可以使得Controller定义更加灵活,可以不用实现Controller接口,请求处理的方法也可以灵活定义

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

    @RequestMapping("/hello.form")
    public String execute() throws Exception {
        return "hello";
    }
}

为了使@Controller注解生效,需要在Spring的XML配置文件中开启组件扫描定义,并指定Controller组件所在包

<context:component-scan base-package="com.tarena.controller"/>

接收请求参数

Spring MVC Web请求提交数据到控制器有下面几种方法

使用HttpServletRequest获取

使用HttpServletRequest获取示例
Spring自动参数注入HttpServletRequest
优点直接,缺点需要自己处理数据类型转换

@RequestMapping("/login-action1.form")
public String checkLogin1(HttpServletRequest req){
    String name = req.getParameter("name");
    String pwd = req.getParameter("pwd");
    System.out.println(name);
    System.out.println(pwd);
    User user = userService.login(name, pwd);
    //...  省略处理过程
    return "success";
}

使用@RequestParam注解

Spring会自动将表单参数注入到方法参数(名称一致)
使用@RequestParam注解,映射不一致的名称
优点参数类型自动转换,但可能出现类型转换异常

@RequestMapping("/login-action2.form")
public String checkLogin2(String name, @RequestParam("pwd")String password, HttpServletRequest req){
    System.out.println(name);
    System.out.println(password);
    User user = userService.login(name, password);
    //... 省略处理过程
    return "success";
}

使用自动机制封装成Bean对象

使用自动机制封装成Bean属性示例
定义User实体,属性名与<form>表单组件的name相同

<form action="login-action3.form">
    用户名:<input type="text" name="name"><br/>
    密码:<input type="password" name="pwd"><br/>
    <input type="submit" value="登录">
 </form>
public class User {
    private String name;
    private String pwd;
    //省略setter和getter方法
}

使用自动机制封装成实体参数示例
在Controller组件处理方法定义User类型参数

@RequestMapping("/login-action3.form")
public String checkLogin3(User user){
    System.out.println(user.getName());
    System.out.println(user.getPwd());
    User u = userService.login(user.getName(), user.getPwd());
    //... 省略处理过程
    return "success";
}

向页面传递

当Controller组件处理后,需要向JSP传值时,用下面方法

直接使用HttpServletRequest和Session

使用ModeAndView对象

使用ModeAndView对象示例
在Controller处理方法完成后返回一个ModelAndView对象, 包含显示视图名和模型数据。

@RequestMapping("/login-action.form")
public ModelAndView checkLogin4(String name, String pwd){
    User user = userService.login(name, pwd);
    Map<String, Object> data = new HashMap<String, Object>();
    data.put("user", user);
    return new ModelAndView("success",data);
}

Model数据会利用HttpServletRequest 的 Attribute传递到JSP页面中。

使用ModelMap参数对象

使用ModelMap参数对象示例
在Controller处理方法中追加一个ModelMap类型参数

@RequestMapping("/login-action5.form")
public String checkLogin5(String name, String pwd,ModelMap model){
    User user  = userService.login(name, pwd);
    model.addAttribute("user", user);
    return "success";
}

ModelMap数据会利用HttpServletRequest 的 Attribute传递到JSP页面中。

使用@ModelAttribute注解

使用@ModelAttribute示例
在Controller方法的参数部分或Bean属性方法上使用

@RequestMapping("/login-action6.from")
public String checkLogin6(
    @ModelAttribute("user") User user){
     //TODO
     return "success";
}

@ModelAttribute("name")
public  String getName(){
    return name;
}

@ModelAttribute数据会利用HttpServletRequest 的Attribute传递到JSP页面中。

Session存储

可以利用HttpServletRequest的getSession()方法访问

@RequestMapping("/login-action5.form")
public String checkLogin5(String name, String pwd,ModelMap model, HttpServletRequest req){
    User user  = userService.login(name, pwd);
    req.getSession().setAttribute("loginUser", user);
    model.addAttribute("user", user);
    return "success";
}

重定向视图

Spring MVC默认采用转发方式定位视图,如果需要重定向方式可采用下面几种方法

使用RedirectView

如果Controller的请求处理方法返回的是ModelAndView对象,可以使用RedirectView方法重定向,示例代码

public ModelAndView checkLogin(){
    //TODO 
    RedirectView view = new RedirectView("login.form");
    return new ModelAndView(view);
}

使用redirect:前缀

如果Controller的请求处理方法返回的是String类型,可以使用“redirect:前缀”方法重定向,示例代码

public String checkLogin(){
    //TODO 
    return "redirect:login.form";
}

猜你喜欢

转载自blog.csdn.net/jsong1025/article/details/50381829