SpringMVC入门就这么简单

什么是SpringMVC?

SpringMVC是Spring家族的一员,Spring是将如今开发中流行的组件进行组合而成的一个框架!它用在基于MVC的表现层开发,相似于struts2框架html

这里写图片描述

为何要使用SpringMVC?

咱们在以前已经学过了Struts2这么一个基于MVC的框架....那么咱们已经学会了Struts2,为啥要要学习SpringMVC呢???java

下面咱们来看一下Struts2不足之处:web

  • 有漏洞【详细能够去搜索】
  • 运行速度较慢【比SpringMVC要慢】
  • 配置的内容较多【须要使用Struts.xml文件】
  • 比较重量级

基于这么一些缘由,而且业内如今SpringMVC已经逐渐把Struts2给替代了...所以咱们学习SpringMVC一方面可以让咱们跟上业界的潮流框架,一方面SpringMVC确实是很是好用spring

能够这么说,Struts2能作的东西,SpringMVC也可以作....express

回顾Struts2开发

在Struts2中,咱们的开发特色是这样的:浏览器

  • Action类继承着ActionSupport类【若是要使用Struts2提供的额外功能,就要继承它】
  • Action业务方法老是返回一个字符串,再由Struts2内部经过咱们手写的Struts.xml配置文件去跳转到对应的view
  • Action类是多例的,接收Web传递过来的参数须要使用实例变量来记住,一般咱们都会写上set和get方法

Struts2的工做流程

这里写图片描述

  • Struts2接收到request请求
  • 将请求转向咱们的过滤分批器进行过滤
  • 读取Struts2对应的配置文件
  • 通过默认的拦截器以后建立对应的Action【多例】
  • 执行完业务方法就返回给response对象

SpringMVC快速入门

导入开发包

前6个是Spring的核心功能包【IOC】,第7个是关于web的包,第8个是SpringMVC包微信

  • org.springframework.context-3.0.5.RELEASE.jar
  • org.springframework.expression-3.0.5.RELEASE.jar
  • org.springframework.core-3.0.5.RELEASE.jar
  • org.springframework.beans-3.0.5.RELEASE.jar
  • org.springframework.asm-3.0.5.RELEASE.jar
  • commons-logging.jar
  • org.springframework.web-3.0.5.RELEASE.jar
  • org.springframework.web.servlet-3.0.5.RELEASE.jar

编写Action

Action实现Controller接口mvc

public class HelloAction implements Controller {
    @Override
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
        return null;
    }
    
}

咱们只要实现handleRequest方法便可,该方法已经说了request和response对象给咱们用了。这是咱们很是熟悉的request和response对象。然而该方法返回的是ModelAndView这么一个对象,这是和Struts2不一样的。Struts2返回的是字符串,而SpringMVC返回的是ModelAndViewapp

ModelAndView其实他就是将咱们的视图路径和数据封装起来而已【咱们想要跳转到哪,把什么数据存到request域中,设置这个对象的属性就好了】框架

public class HelloAction implements Controller {
    @Override
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {


        ModelAndView modelAndView = new ModelAndView();

        //跳转到hello.jsp页面。
        modelAndView.setViewName("/hello.jsp");
        return modelAndView;
    }
}

注册核心控制器

在Struts2中,咱们想要使用Struts2的功能,那么就得在web.xml文件中配置过滤器。而咱们使用SpringMVC的话,咱们是在web.xml中配置核心控制器

<!-- 注册springmvc框架核心控制器 -->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!--到类目录下寻找咱们的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:hello.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!--映射的路径为.action-->
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

建立SpringMVC控制器

咱们在hello.xml配置文件中把SpringMVC的控制器建立出来

<!--
        注册控制器
        name属性的值表示的是请求的路径【也就是说,当用户请求到/helloAction时,就交由HelloAction类进行处理】
    -->
    <bean class="HelloAction" name="/hello.action"></bean>

访问

当咱们在浏览器访问http://localhost:8080/hello.action的时候,Spring会读取到咱们的访问路径,而后对比一下咱们的配置文件中是否有配置/hello.action,若是有。那么就交由对应的Action类来进行处理。Action类的业务方法将其请求输出到hello.jsp页面上。

这里写图片描述


SpringMVC工做流程

这里写图片描述

  • 用户发送请求
  • 请求交由核心控制器处理
  • 核心控制器找到映射器,映射器看看请求路径是什么
  • 核心控制器再找到适配器,看看有哪些类实现了Controller接口或者对应的bean对象
  • 将带过来的数据进行转换,格式化等等操做
  • 找到咱们的控制器Action,处理完业务以后返回一个ModelAndView对象
  • 最后经过视图解析器来对ModelAndView进行解析
  • 跳转到对应的JSP/html页面

上面的工做流程中,咱们是没有讲过映射器,适配器,视图解析器这样的东西的。可是SpringMVC的环境仍是被咱们搭建起来了。

下面就由我来一个一个来介绍他们是有什么用的!

映射器

咱们在web.xml中配置规定只要是.action为后缀的请求都是会通过SpringMVC的核心Servlet

当咱们接收到请求的时候,咱们发现是hello.action,是会通过咱们的核心Servlet的,那么核心Servlet就会去找有没有专门的Action类来处理hello.action请求的

也就是说:映射器就是用于处理“什么样的请求提交给Action”处理【默承认省略的】.....

其实咱们在快速入门的例子已经配置了:name属性就是规定了hello.action到HelloAction控制器中处理

<!--
        注册控制器
        name属性的值表示的是请求的路径【也就是说,当用户请求到/helloAction时,就交由HelloAction类进行处理】
    -->
    <bean class="HelloAction" name="/hello.action"></bean>

映射器默认的值是这样的:

<!-- 注册映射器(handler包)(框架)【可省略】 -->
      <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
       </bean>

固然了,上面咱们在建立控制器的时候【也就是HelloAction】能够不使用name属性来指定路径,可使用咱们的映射器来配置。如如下的代码:

<bean class="HelloAction" id="helloAction"></bean>

    <!-- 注册映射器(handler包)(框架) -->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/hello.action">helloAction</prop>
            </props>
        </property>
    </bean>

当咱们须要多个请求路径都交由helloAction控制器来处理的话,咱们只要添加prop标签就好了!

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/hello.action">helloAction</prop>
                <prop key="/bye.action">helloAction</prop>
            </props>
        </property>
    </bean>

这里写图片描述


适配器

当咱们映射器找到对应的Action来处理请求的时候,核心控制器会让适配器去找该类是否实现了Controller接口【默承认省略的】

也就是说:适配器就是去找实现了Controller接口的类

<!-- 适配器【可省略】 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

视图解析器

咱们把结果封装到ModelAndView之后,SpringMVC会使用视图解析器来对ModelAndView进行解析。【默承认省略的】

也有一种状况是不能省略的。咱们在快速入门的例子中,将结果封装到ModelAndView中,用的是绝对真实路径!若是咱们用的是逻辑路径,那么就必须对其配置,不然SpringMVC是找不到对应的路径的。

那什么是逻辑路径呢???咱们在Struts2中,返回的是"success"这样的字符串,从而跳转到success.jsp这样的页面上。咱们就能够把"success"称做为逻辑路径

在Action中返回hello,hello是一个逻辑路径。须要咱们使用视图解析器把逻辑路基补全

public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {


        ModelAndView modelAndView = new ModelAndView();

        //跳转到hello.jsp页面。
        modelAndView.setViewName("hello");
        return modelAndView;
    }

若是不使用视图解析器的话,那么就会找不到页面:

这里写图片描述

所以,咱们须要配置视图解析器

<!--
    若是Action中书写的是视图逻辑名称,那么视图解析器就必须配置
    若是Action中书写的是视图真实名称,那么视图解析器就可选配置
-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 路径前缀 -->
        <property name="prefix" value="/"/>
        <!-- 路径后缀 -->
        <property name="suffix" value=".jsp"/>
        <!-- 前缀+视图逻辑名+后缀=真实路径 -->
    </bean>

控制器

ParameterizableViewController

咱们在以前使用Struts2的时候,若是仅仅要跳转到某个WEB-INF/JSP页面,也要写业务方法。而业务方法也仅仅是返回一个简单的字符串。

以下的代码:

public String home(){

    return "home";
}
<package name="nsfw-home" namespace="/nsfw" extends="struts-default">

        <action name="nsfw_*" class="zhongfucheng.nsfw.HomeAction" method="{1}">
            <result name="{1}">/WEB-INF/jsp/nsfw/{1}.jsp</result>
        </action>
    </package>

在SpringMVC中,若是仅仅是跳转到某个视图上,咱们能够省略该Action和业务方法。配置的Action只要继承着ParameterizableViewController这个类就好了

<!-- 专用于jsp到jsp/html的转发控制器 -->
    <bean name="/ok.action" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <!-- 转发到真实视图名 -->
        <property name="viewName" value="/WEB-INF/ok.jsp"/>
    </bean>

这里写图片描述

  • 2017年9月26日15:57:45 如今看来, 好像仍是在方法上写更好。我以为统一管理起来会更加方便

AbstractCommandController

到目前为止,咱们都没有将SpringMVC是怎么接收web端传递过来的参数的。

咱们在Struts2中,只要在Action类上写对应的成员变量,给出对应的set和get方法。那么Struts2就会帮咱们把参数封装到对应的成员变量中,是很是方便的。

那么咱们在SpringMVC中是怎么获取参数的呢????咱们是将Action继承AbstractCommandController这么一个类的。

public class HelloAction extends AbstractCommandController {
    
    @Override
    protected ModelAndView handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, BindException e) throws Exception {
           
        return null;
    } 
}

在讲解该控制器以前,首先咱们要明白SpringMVC控制器一个与Struts2不一样的地方:SpringMVC的控制器是单例的,Struts2的控制器是多例的

也就是说:Struts2收集变量是定义成员变量来进行接收,而SpringMVC做为单例的,是不可能使用成员变量来进行接收的【由于会有多个用户访问,就会出现数据不合理性】

那么SpringMVC做为单例的,他只能经过方法的参数来进行接收对应的参数只有方法才能保证不一样的用户对应不一样的数据

实体

实体的属性要和web页面上的name提交过来的名称是一致的。这和Struts2是同样的!

public class User {

    private String id;
    private String username;

    public User() {
    }

    public User(String id, String username) {
        this.id = id;
        this.username = username;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", username='" + username + '\'' +
                '}';
    }
}

提交参数的JSP

<form action="${pageContext.request.contextPath}/hello.action" method="post">
    <table align="center">
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>编号</td>
            <td><input type="text" name="id"></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="提交">
            </td>
        </tr>
    </table>

</form>

配置Action处理请求

<bean class="HelloAction" id="helloAction"></bean>


    <!-- 注册映射器(handler包)(框架) -->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/hello.action">helloAction</prop>
            </props>
        </property>
    </bean>

Action接收参数

public class HelloAction extends AbstractCommandController {

    /*设置无参构造器,里边调用setCommandClass方法,传入要封装的对象*/
    public HelloAction() {
        this.setCommandClass(User.class);
    }

    /**
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o  这里的对象就表示已经封装好的了User对象了。!
     * @param e
     * @return
     * @throws Exception
     */
    @Override
    protected ModelAndView handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, BindException e) throws Exception {

        User user = (User) o;

        System.out.println(user);

        ModelAndView modelAndView = new ModelAndView();
        //跳转到ok.jsp
        modelAndView.setViewName("/WEB-INF/ok.jsp");
        //将数据封装到ModelAndView中
        modelAndView.addObject("USER", user);
        return modelAndView;
    }
}

效果:

这里写图片描述

小总结

这里写图片描述

这里写图片描述

Struts2和SpringMVC存值的区别:

这里写图片描述

  • SpringMVC的工做流程:

    • 用户发送HTTP请求,SpringMVC核心控制器接收到请求
    • 找到映射器看该请求是否交由对应的Action类进行处理
    • 找到适配器看有无该Action类
    • Action类处理完结果封装到ModelAndView中
    • 经过视图解析器把数据解析,跳转到对应的JSP页面
  • 控制器介绍了两种:

    • ParameterizableViewController

      • 可以实现跳转到WEB-INF下资源,并不用写处理方法
    • AbstractCommandController

      • 能够实现对参数数据的封装

若是文章有错的地方欢迎指正,你们互相交流。 习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y
相关文章
相关标签/搜索