mybatis+spring的TODO小项目记录(七)上手spring mvc

早在本科期间十分流行的java web框架是SSH,即struts2、spring和hibernate。struts2是一个MVC框架,在web开发中作为控制器来帮助我们建立模型与视图的数据交互,而对于MVC框架来说,如今更加流行的是本篇的主角SpringMVC。看到这个名字也会知道它和spring是有关系的,其实springMVC是依赖于spring的。spring的两大核心是IOC(控制反转,也叫依赖注入DI)和AOP(面向切面编程)。hibernate是一个ORM(对象关系映射)框架,它将POJO与数据表建立映射关系,可以自动生成SQL语句并执行。在这个项目中使用的mybatis是另一个ORM框架,它主要着力于SQL与POJO之间的映射关系,因此可以进行更为细致的SQL优化。

本文介绍的是上述中的Spring MVC的配置过程。Spring MVC是一个基于DispatcherServlet的MVC框架,每一个request请求都是由DispatcherServlet负责转发给相应的Handler,然后再由Handler处理并返回相应的视图(View)和模型(Model)。

首先看一下目前的项目结构,如下图所示:
mybatis+spring的TODO小项目记录(七)上手spring mvc_第1张图片

  • src目录下有以下几个文件夹:
    • src/main/java
    • src/main/resources
    • src/test/java
  • web目录是java web项目的文件夹,下面有:
    • WEB-INF,存放jsp页面和其他静态文件,该目录下的文件无法通过web直接访问到
    • index.jsp,可以直接通过web url访问到

pom.xml

现在我们需要使用spring mvc,因此首先需要导入所需的jar包。只需要在pom.xml文件中加入spring mvc的依赖,maven就可以将所需的以下包导入项目中:

  • commons-logging
  • spring-aop
  • spring-beans
  • spring-context
  • spring-core
  • spring-express
  • spring-web
  • spring-webmvc

添加依赖如下:


        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>${spring-version}version>
        dependency>

这里为了以后修改spring mvc版本方便,使用了参数的形式,spring-version可以在dependencies节点之前定义:

<properties>
        <spring-version>4.3.7.RELEASEspring-version>
properties>

web.xml

由于是web项目,我们首先需要配置web.xml文件,粘贴如下:


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>TODOdisplay-name>

    <servlet>
        
        <servlet-name>dispatcherservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        
        
            
            
        
        <load-on-startup>1load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatcherservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>

    <filter>
        <filter-name>encodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>UTF-8param-value>
        init-param>
        <init-param>
            <param-name>forceEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>encodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>
    <session-config>
        <session-timeout>60session-timeout>
    session-config>

    <context-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:applicationContext.xmlparam-value>
    context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
    listener>

web-app>

servlet标签中我们定义了DispatcherServlet以及映射URL。该servlet通过servlet-name定义了名字dispatcher,默认情况下spring会自动到WEB-INF下扫描dispatcher-servlet.xml文件,这里我们也可以通过init-param中的contextConfigLocation指定配置文件,如类路径下的applicationContext.xml文件。

servlet标签内的load-on-startup元素是可选的,如果存在,则该servlet会在应用程序启动时装载并调用它的init方法,否则会在该servlet的第一次请求时加载。

contextLoaderListener指定了IOC容器初始化的方法,这里指向了类路径下的applicationContext.xml文件。使用applicationContext.xml文件时,需要在web.xml中添加listener,即org.springframework.web.context.ContextLoaderListener

其实可以看到这里有两个contextConfigLocation,一个是applicationContext.xml,另一个是在servlet节点中的dispatcher-servlet.xml。这两个文件都可以进行spring的配置,至于两者的区别,我们查看spring的官方文档的说明:

    Spring lets you define multiple contexts in a parent-child hierarchy.
    The applicationContext.xml defines the beans for the "root webapp context", i.e. the context associated with the webapp.
    The spring-servlet.xml (or whatever else you call it) defines the beans for one servlet's app context. There can be many of these in a webapp, one per Spring servlet (e.g. spring1-servlet.xml for servlet spring1, spring2-servlet.xml for servlet spring2).
    Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa.
    All Spring MVC controllers must go in the spring-servlet.xml context.
    In most simple cases, the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there's not really much point, unless you have a specific use for it. 

可以看到applicationContext.xml不是必需的,它定义的是整个web应用的上下文,与其他xxx-servlet.xml是父子层级关系。xxx-servlet.xml定义了每个对应的servlet的上下文,所有的MVC控制器必需定义在xxx-servlet.xml中。

dispatcher-servlet.xml


<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-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd"
       default-lazy-init="true">

    
    <mvc:annotation-driven>mvc:annotation-driven>

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

    
    

    
    <mvc:resources mapping="/js/**" location="/WEB-INF/static/js/"/>
    <mvc:resources mapping="/styles/**" location="/WEB-INF/static/css/"/>
    <mvc:resources mapping="/images/**" location="/WEB-INF/static/img/"/>
    <mvc:resources location="/WEB-INF/pages/" mapping="/pages/**"/>

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

beans>

applicationContext.xml

目前没有什么bean,因此是空的。


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

beans>

Controller

接下来我们就可以定义第一个Controller,代码如下:

package com.loveqh.todo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Created by WL on 2017-04-27.
 */

@Controller
@RequestMapping(value = "/user")
public class LoginController {

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String index() {
        System.out.println("用户登录");
        return "index";
    }
}

这样启动tomcat之后,访问http://localhost:8080/user/login时,DispatcherServlet会将请求转发到LoginController的index方法进行处理。index方法返回一个字符串“index”,根据上面的dispatcher-servlet.xml中的视图解析器定义的前缀和后缀,spring会返回/WEB-INF/pages/index.jsp页面。

在第一次尝试运行时,出现了报错,提示找不到jar包,错误如下:

org.apache.catalina.core.StandardContext listenerStart
  严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
  java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1892)         

但是通过仔细检查,spring-context包已经通过maven成功导入了,仍然报错。后经查阅资料,需要将web部署所需的包都拷贝至out目录下的WEB-INF/lib中,将jar包复制过去之后,错误果然消失。

至此,SpringMVC配置大功告成!下一步,我们将使用SpringMVC完成项目的用户注册和登录功能。

你可能感兴趣的:(java,spring,springmvc)