EchoDemo's Blogs

springmvc学习笔记(1)-框架原理和入门配置

绿槐高柳咽新蝉。薰风初入弦。碧纱窗下水沉烟。棋声惊昼眠。

微雨过,小荷翻。榴花开欲然。玉盆纤手弄清泉。琼珠碎却圆。

—-宋·苏轼《阮郎归·初夏》

本文主要介绍springmvc的框架原理,并通过一个入门程序展示环境搭建,配置以及部署调试。springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。


springmvc框架原理

官网示意图如下:



"Springmvc"

SpringMVC的核心架构:



"Springmvc原理"

组件及其作用:

(1)前端控制器(DispatcherServlet):接收请求,响应结果,相当于转发器,中央处理器。减少了其他组件之间的耦合度。

(2)处理器映射器(HandlerMapping):根据请求的url查找Handler。

(3)Handler处理器:按照HandlerAdapter的要求编写。

(4)处理器适配器(HandlerAdapter):按照特定规则(HandlerAdapter要求的规则)执行Handler。

(5)视图解析器(ViewResolver):进行视图解析,根据逻辑视图解析成真正的视图(View)。

(6)视图(View):View是一个接口实现类试吃不同的View类型(jsp,pdf等等)。

具体流程:

1.发起请求到前端控制器(DispatcherServlet)。

2.前端控制器请求处理器映射器(HandlerMapping)查找Handler(可根据xml配置、注解进行查找)。

3.处理器映射器(HandlerMapping)向前端控制器返回Handler。

4.前端控制器调用处理器适配器(HandlerAdapter)执行Handler。

5.处理器适配器(HandlerAdapter)去执行Handler。

6.Handler执行完,给适配器返回ModelAndView(Springmvc框架的一个底层对象)。

7.处理器适配器(HandlerAdapter)向前端控制器返回ModelAndView。

8.前端控制器(DispatcherServlet)请求视图解析器(ViewResolver)进行视图解析,根据逻辑视图名解析成真正的视图(jsp)。

9.视图解析器(ViewResolver)向前端控制器(DispatcherServlet)返回View。

10.前端控制器进行视图渲染,即将模型数据(在ModelAndView对象中)填充到request域。

11.前端控制器向用户响应结果。

springmvc入门程序

一个展示商品列表的小页面

1、环境搭建

(1)new->project->maven->勾选create from archetype->选中webapp。

(2)在src/main下新建java文件夹,标记为Sources Root。在在src/main下新建resources文件夹,标记为Resources Root。

2、添加依赖

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>1.7</maven.compiler.source>
  <maven.compiler.target>1.7</maven.compiler.target>
  <spring-base-version>4.2.4.RELEASE</spring-base-version>
</properties>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring-base-version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${spring-base-version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring-base-version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring-base-version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring-base-version}</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
  </dependency>
  <dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
  </dependency>
</dependencies>

build标签的finalName要和Artifacts的output directory一致:

<finalName>springmvcfirst</finalName>

3、配置文件

(1)配置前端控制器

<?xml version="1.0" encoding="UTF-8"?>

<web-app  version="2.3"
          xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_3.xsd">
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
      若不配置,默认加载WEB-INF/servlet名称-servlet(springmvc-servlet.xml)
    -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!--
    第一种:*.action,访问以.action结尾,由DispatcherServlet进行解析
    第二种:/,所有访问的地址由DispatcherServlet进行解析,对静态文件的解析需要配置不让DispatcherServlet进行解析,
            使用此种方式和实现RESTful风格的url
    第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时,仍然会由DispatcherServlet解析jsp地址,
            不能根据jsp页面找到handler,会报错
    -->
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>

(2)创建springmvc.xml(springmvc.xml放在resources目录下)

<?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.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

</beans>

(3)在springmvc.xml中配置Handler

<bean name="/queryItems.action" class="com.echodemo.ssm.controller.ItemsController"/>

(4)在springmvc.xml中配置处理器映射器

<!-- 处理器映射器
将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)
所有的映射器都实现HandlerMapping接口
-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

(5)在springmvc.xml中配置处理器适配器

<!-- 配置处理器适配器,所有处理器适配器都实现了HandlerAdapter接口 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

源码:

public boolean supports(Object handler) {
        return handler instanceof Controller;
}

此适配器能执行实现Controller接口的Handler

(6)在springmvc.xml中配置视图解析器

<!-- 视图解析器
解析jsp,默认使用jstl,classpath下要有jstl的包
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>

在springmvc.xml中视图解析器配置前缀和后缀:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置jsp路径的前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 配置jsp路径的后缀 -->
        <property name="suffix" value=".jsp"/>
</bean>

程序中不用指定前缀和后缀:

// 指定视图
// 下边的路径,如果在视图解析器中配置jsp的路径前缀和后缀,修改为items/itemsList
// modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");

// 下边的路径配置就可以不在程序中指定jsp路径的前缀和后缀
modelAndView.setViewName("items/itemsList");

部署调试

Items类:

package com.echodemo.ssm.bean;

import java.util.Date;

public class Items {
    private Integer id;

    private String name;

    private Float price;

    private String pic;

    private Date createtime;

    private String detail;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic == null ? null : pic.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail == null ? null : detail.trim();
    }
}

实现Controller接口的ItemsController:

package com.echodemo.ssm.controller;

import com.echodemo.ssm.bean.Items;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import java.util.ArrayList;
import java.util.List;

public class ItemsController implements Controller {

    @Override
    public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
        // 调用service查找数据库,查询商品列表,这里使用静态数据模拟
        List<Items> itemsList = new ArrayList<>();
        // 向list中填充静态数据
        Items items_1 = new Items();
        items_1.setName("联想笔记本");
        items_1.setPrice(5000f);
        items_1.setDetail("Think Pad T430联想笔记本");

        Items items_2 = new Items();
        items_2.setName("苹果手机");
        items_2.setPrice(5000f);
        items_2.setDetail("Iphone6苹果手机");
        itemsList.add(items_1);
        itemsList.add(items_2);
        // 返回ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        // 相当于request的setAttribute,在JSP页面中通过itemsList取数据
        modelAndView.addObject("itemsList", itemsList);
        // 指定视图
        modelAndView.setViewName("items/itemsList");
        return modelAndView;
    }

}

1、在idea中EditConfigurations,添加一个local的tomcat server。

2、设置tomcat启动路径,并且配置为修改自动更新(这样就不需要总是重启了)


"Tomcat1"

3、需要相应设置application context为上一步默认url后加的/springmvcfirst


"Tomcat2"

4、最后在tomcat的webapps目录下新建一个同名的文件夹,将output directory置为它。


"Tomcat3"

5、相关问题

HTTP Status 404 - 
处理器映射器根据url找不到Handler,说明url错误

HTTP Status 404 -/springmvc/WEB-INF/jsp/items/itemsLists.jsp 
处理器映射器根据url找到了Handler,转发的jsp页面找不到
🐶 您的支持将鼓励我继续创作 🐶
-------------本文结束感谢您的阅读-------------