百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

SpringMVC学习笔记文本版(一)

toyiye 2024-06-21 12:17 13 浏览 0 评论

1.SpringMVC 的流程走向

第一步:发起请求到前端控制器(DispatcherServlet).

第二步:前段控制器请求处理映射器(HandlerMapping)查找 Handler.

通过xml配置文件、注解。

第三步:处理映射器 HandlerMapping 向前端控制器返回 Handler.

第四步:前端控制器通过处理器适配器(HandlerAdapter)执行Handler.

第五步:处理器适配器执行Handler。

第六步:Handler执行完给处理器适配器(HandlerAdapter)返回ModelAndView.

第七步:处理器适配器(HandlerAdapter)向前端控制器(DispatcherServlet)返回ModelAndView.

ModelAndView是SpringMVC框架底层的一个对象,ModelAndView包括Model和View.

第八步:前段控制器(DispatcherServlet)请求视图解析器解析视图.

根据逻辑视图名解析成真正的视图(物理视图包括jsp、freemarker、excel、pdf等)

第九步:视图解析器向前端控制器返回View.

第十步:前端控制器进行视图渲染。

视图渲染:把模型数据(在ModelAndView对象中)填充到Request域(RequestScope).

第十一步:前端控制器向用户响应(Response)请求结果。

2.组件:

2.1.前端控制器(DispatcherServlet)(不需要程序员开发,除非进行底层封装)

作用:接收请求、响应结果。相当于转发器。

有中央处理器的作用,有了前端控制器(DispatcherServlet),减少了其它组件之间的耦合度。

2.2.处理映射器(HandlerMapping)(不需要程序员开发)

作用:根据请求url查找Handler.

2.3.处理器适配器(HandlerAdapter)(不需要程序员开发)

作用:按照特定的规则(HandlerAdapter要求的规则)去执行Handler.

2.4.Handler处理器(####需要程序员开发)

注意:开发Handler时,要按照HandlerAdapter的要求去开发,适配器才能正确去执行Handler.

2.5.视图解析器(ViewResovler)(不需要程序员开发)

作用:进行视图解析,根据逻辑视图名解析成真正的视图(View).

2.6.视图(View)($$$需要程序员开发jsp)

View是一个接口,实现类支持不同的类型(jsp、freemarker、pdf...)

3.入门程序:《商品订单管理》

3.1)需求分析:订单表、商品表、商品明细表、用户表

3.1.1数据库级别

订单表 hx_order

商品表 hx_shop

购买明细表 hx_orderDetail

用户表 hx_user

需求:商品订单查询

3.1.2 业务级别:

1.一个用户可以创建多个订单:用户表到订单表是一对多

2.一个订购单只能对应一个用户:订单表到用户表一对一

3.一个订单可以对应多个购买明细:订单表到购买明细表是一对多

4.一个购买明细只能对应一个订单:购买明细表到订单表是一对一

5.一个购买明细只能对应一个商品:购买明细表到商品表是一对一

6.一个商品可以以对应多个购买明细:商品表到购买明细表是一对多

7.用户表 1:n 订单表 1:n 购买明细表 1:1 商品表,结论:用户表 1:n 商品表

8.商品表 1:n 购买明细表 1:1 订单表 1:1 用户表,结论:商品表 1:n 用户表

9.用户表 n:n 商品表

3.1.3 业务流程:

1.管理员维护商品

2.用户挑选商品,购买,创建订单。

3.1.4.创建数据库:

/*

SQLyog v10.2

MySQL - 5.1.72-community : Database - mybatis

*********************************************************************

*/

/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

/*Table structure for table `items` */

CREATE TABLE `items` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(32) NOT NULL COMMENT '商品名称',

`price` float(10,1) NOT NULL COMMENT '商品定价',

`detail` text COMMENT '商品描述',

`pic` varchar(64) DEFAULT NULL COMMENT '商品图片',

`createtime` datetime NOT NULL COMMENT '生产日期',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Table structure for table `orderdetail` */

CREATE TABLE `orderdetail` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`orders_id` int(11) NOT NULL COMMENT '订单id',

`items_id` int(11) NOT NULL COMMENT '商品id',

`items_num` int(11) DEFAULT NULL COMMENT '商品购买数量',

PRIMARY KEY (`id`),

KEY `FK_orderdetail_1` (`orders_id`),

KEY `FK_orderdetail_2` (`items_id`),

CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,

CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Table structure for table `orders` */

CREATE TABLE `orders` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`user_id` int(11) NOT NULL COMMENT '下单用户id',

`number` varchar(32) NOT NULL COMMENT '订单号',

`createtime` datetime NOT NULL COMMENT '创建订单时间',

`note` varchar(100) DEFAULT NULL COMMENT '备注',

PRIMARY KEY (`id`),

KEY `FK_orders_1` (`user_id`),

CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*Table structure for table `user` */

CREATE TABLE `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`username` varchar(32) NOT NULL COMMENT '用户名称',

`birthday` date DEFAULT NULL COMMENT '生日',

`sex` char(1) DEFAULT NULL COMMENT '性别',

`address` varchar(256) DEFAULT NULL COMMENT '地址',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;

/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;

/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

/*

SQLyog v10.2

MySQL - 5.1.72-community : Database - mybatis

*********************************************************************

*/

/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

/*Data for the table `items` */

insert into `items`(`id`,`name`,`price`,`detail`,`pic`,`createtime`) values (1,'台式机',3000.0,'该电脑质量非常好!!!!',NULL,'2015-02-03 13:22:53'),(2,'笔记

本',6000.0,'笔记本性能好,质量好!!!!!',NULL,'2015-02-09 13:22:57'),(3,'背包',200.0,'名牌背包,容量大质量好!!!!',NULL,'2015-02-06 13:23:02');

/*Data for the table `orderdetail` */

insert into `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) values (1,3,1,1),(2,3,2,3),(3,4,3,4),(4,4,2,3);

/*Data for the table `orders` */

insert into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL),(4,1,'1000011','2015-02-03

13:22:41',NULL),(5,10,'1000012','2015-02-12 16:13:23',NULL);

/*Data for the table `user` */

insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河

郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;

/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;

/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

3.2.环境搭建:

jdk(8)、mysql(5.7.13)、eclipse(sts3.8.1)

spring jar

mybatis jar

辅助 jar

3.3.创建web工程

3.3.1.修改classes输出目录为WebRoot/WEB-INF/classes,WEB目录改为WebRoot方便使用导入到myeclipse

3.3.2.工程默认字符集修改为UTF-8

3.3.3.自动提示,加入.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,延迟时间改为150-200毫秒

3.3.4.编辑显示字体改为Courier New.

3.3.5.我这里使用的IDE为sts,的maven创建工程

3.3.6.pom.xml内容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>org.hxweb.web</groupId>

<artifactId>ssmhxweb</artifactId>

<packaging>war</packaging>

<version>0.0.1-SNAPSHOT</version>

<name>ssmhxweb Maven Webapp</name>

<url>http://maven.apache.org</url>

<properties>

<!-- spring版本号 -->

<spring.version>4.3.1.RELEASE</spring.version>

<!-- mybatis版本号 -->

<mybatis.version>3.3.0</mybatis.version>

<!-- log4j日志文件管理包版本 -->

<slf4j.version>1.7.7</slf4j.version>

<log4j.version>1.2.17</log4j.version>

</properties>

<dependencies>

<!-- spring核心包 -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-oxm</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-tx</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-webmvc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aop</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-test</artifactId>

<version>${spring.version}</version>

</dependency>

<!-- mybatis核心包 -->

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>${mybatis.version}</version>

</dependency>

<!-- mybatis/spring包 -->

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis-spring</artifactId>

<version>1.2.2</version>

</dependency>

<!-- 导入java ee jar 包 -->

<dependency>

<groupId>javax</groupId>

<artifactId>javaee-api</artifactId>

<version>7.0</version>

</dependency>

<!-- 导入DB2数据库连接 jar 包 -->

<dependency>

<groupId>db2jcc</groupId>

<artifactId>db2jcc</artifactId>

<version>1.4</version>

</dependency>

<!-- 导入Mysql数据库链接jar包 -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.39</version>

</dependency>

<!-- 导入阿里巴巴数据库的jar包,用来在applicationContext.xml中配置数据库 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.0.25</version>

</dependency>

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.8.4</version>

</dependency>

<!-- 导入dbcp的jar包,用来在applicationContext.xml中配置数据库 -->

<dependency>

<groupId>commons-dbcp</groupId>

<artifactId>commons-dbcp</artifactId>

<version>1.2.2</version>

</dependency>

<!-- JSTL标签类 -->

<dependency>

<groupId>jstl</groupId>

<artifactId>jstl</artifactId>

<version>1.2</version>

</dependency>

<!-- 日志文件管理包 -->

<!-- log start -->

<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>${log4j.version}</version>

</dependency>

<!-- Attention: Be sure nothing pulls in an old dependency with groupId

"freemarker" (without the "org."), because then you will end up with two

freemarker.jar-s and unpredictable behavior! -->

<dependency>

<groupId>org.freemarker</groupId>

<artifactId>freemarker</artifactId>

<version>2.3.25-incubating</version>

</dependency>

<!-- 格式化对象,方便输出日志 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>fastjson</artifactId>

<version>1.2.3</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-api</artifactId>

<version>${slf4j.version}</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-log4j12</artifactId>

<version>${slf4j.version}</version>

</dependency>

<!-- log end -->

<!-- 映入JSON -->

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-core</artifactId>

<version>2.5.2</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.core</groupId>

<artifactId>jackson-databind</artifactId>

<version>2.5.2</version>

</dependency>

<!-- 上传组件包 -->

<dependency>

<groupId>commons-fileupload</groupId>

<artifactId>commons-fileupload</artifactId>

<version>1.3.1</version>

</dependency>

<dependency>

<groupId>commons-io</groupId>

<artifactId>commons-io</artifactId>

<version>2.4</version>

</dependency>

<dependency>

<groupId>commons-codec</groupId>

<artifactId>commons-codec</artifactId>

<version>1.9</version>

</dependency>

<dependency>

<groupId>org.codehaus.jackson</groupId>

<artifactId>jackson-core-asl</artifactId>

<version>1.9.13</version>

</dependency>

<dependency>

<groupId>org.apache.bval</groupId>

<artifactId>bval-jsr</artifactId>

<version>1.1.1</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<!-- 表示开发的时候引入,发布的时候不会加载此包 -->

<scope>test</scope>

</dependency>

</dependencies>

<build>

<finalName>ssmhxweb</finalName>

<resources>

<resource>

<directory>src/main/java</directory>

<includes>

<include>**/*.properties</include>

<include>**/*.xml</include>

</includes>

<filtering>false</filtering>

</resource>

<resource>

<directory>src/main/resources</directory>

<includes>

<include>**/*.properties</include>

<include>**/*.xml</include>

</includes>

<filtering>false</filtering>

</resource>

</resources>

</build>

</project>

3.3.7.配置前端控制器

在web.xml中配置:

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

id="WebApp_ssmhxweb" version="3.0">

<display-name>ssmhxweb</display-name>

<!--配置前端控制器 -->

<servlet>

<servlet-name>springmvc</servlet-name>

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

<!-- contextConfigLocation 1.配置springmvc需要加载的配置文件(配置处理器映射器、处理器适配器、处理器、视图解析器等)

2.如果不配置contextConfigLocation,就会默认加载/WEB-INF/servlet名称-servlet.xml (这里是springmvc-servlet.xml) -->

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:config/springmvc.xml</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>springmvc</servlet-name>

<!-- 多种配置方式: 第一种:*.action,*.do 访问以.action、.do为结尾的由DispatcherServlet来解析。

第二种:/ 所有访问地址都由DispatcherServlet来解析,对应静态文件需要配置不由DispatcherServlet进行解析。

使用此种方式可以实现RESTFul风格的url

第三种:/* 这种配置方式存在问题(不要用这种方式):最终转发到一个jsp页面时,

仍然会由由DispatcherServlet解析jsp页面,不能根据jsp页面找到对应的Handler,会报错。也不符合我们设计思想。

-->

<url-pattern>*.action</url-pattern>

</servlet-mapping>

</web-app>

3.3.8.配置处理器适配器

3.3.8.1.配置 <!-- 配置处理器适配器 :所有的处理器适配器都实现了HandlerAdapter接口 -->

<bean

class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

3.3.8.2.查看源码:

public class SimpleControllerHandlerAdapter implements HandlerAdapter {

@Override

public boolean supports(Object handler) {

return (handler instanceof Controller);

}

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

public interface Controller {

/**

* Process the request and return a ModelAndView object which the DispatcherServlet

* will render. A {@code null} return value is not an error: it indicates that

* this object completed request processing itself and that there is therefore no

* ModelAndView to render.

* @param request current HTTP request

* @param response current HTTP response

* @return a ModelAndView to render, or {@code null} if handled directly

* @throws Exception in case of errors

*/

ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}

3.3.9.编写 Handler

需要实现 Controller 接口,才能由 org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter适配器来执行。

package org.hxweb.web.ssm.controller;

import java.util.ArrayList;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.hxweb.web.ssm.pojo.Items;

import org.hxweb.web.ssm.pojo.Orders;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.Controller;

/**

*

* @author Administrator

*

*/

public class ItemsController1 implements Controller{

@Override

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

/*

* 调用service来查找 数据库,查询商品列表,这里使用静态数据模拟

*/

List<Items> itemsList = new ArrayList<Items>();

//向list中填充静态数据

Items items1 = new Items();

items1.setName("联想");

items1.setPrice(6000f);

items1.setDetail("联想 Tinkpad E430");

Items items2 = new Items();

items2.setName("戴尔");

items2.setPrice(5800f);

items2.setDetail("戴尔笔记本");

Items items3 = new Items();

items3.setName("华硕");

items3.setPrice(5900f);

items3.setDetail("华硕笔记本");

itemsList.add(items1);

itemsList.add(items2);

itemsList.add(items3);

//为返回ModelAndView填充数据和指定视图

ModelAndView modelAndView = new ModelAndView();

//相当于request.setAtttibute,在jsp页面可以通过itemsList获取商品列表数据

modelAndView.addObject("itemsList", itemsList);

//指定返回视图

modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");

//返回ModelAndView

return modelAndView;

}

}

3.3.10.视图的编写

itemsList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<!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>查询商品列表</title>

</head>

<body>

<form action="${pageContext.request.contextPath }/item/queryItem.action" method="post">

查询条件:

<table width="100%" border=1>

<tr>

<td><input type="submit" value="查询"/></td>

</tr>

</table>

商品列表:

<table width="100%" border=1>

<tr>

<td>商品名称</td>

<td>商品价格</td>

<td>生产日期</td>

<td>商品描述</td>

<td>操作</td>

</tr>

<c:forEach items="${itemsList }" var="item">

<tr>

<td>${item.name }</td>

<td>${item.price }</td>

<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>

<td>${item.detail }</td>

<td><a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a></td>

</tr>

</c:forEach>

</table>

</form>

</body>

</html>

3.3.11.配置处理器映射器

<!-- 配置处理器映射器 :BeanNameUrlHandlerMapping映射器 把bean的name作为url查找,需要在配置Handler是指定bean的name(就是url) -->

<bean

class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

3.3.12.配置 Handler

将编写的 Handler 在 Spring 容器中加载

<!-- 配置 Handler -->

<bean name="/queryItems.action" class="org.hxweb.web.ssm.controller.ItemsController1"></bean>

3.3.13.配置视图解析器

需要配置解析jsp的视图解析器

<!-- 配置视图解析器 :InternalResourceViewResolver视图解析器,是解析jsp的视图解析器,默认支持jstl标签 需要有jstl的jar包-->

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

public class InternalResourceViewResolver extends UrlBasedViewResolver {

private static final boolean jstlPresent = ClassUtils.isPresent(

"javax.servlet.jsp.jstl.core.Config", InternalResourceViewResolver.class.getClassLoader());

private Boolean alwaysInclude;

3.3.14.调试

3.3.14.1调试目标访问地址: http://localhost:8080/ssmhxweb/queryItems.action

3.3.14.2.处理器映射器根据url找不到 Handler 报如下错误提示(先检查url输入是否正确):

HTTP Status 404 -

type Status report

message

description The requested resource is not available.

--------------------------------------------------------------------------------

Apache Tomcat/8.0.35

3.3.14.3.处理器映射器根据url找到了 Handler 转发jsp页面地址不正确,在对应Handler中改正对应jsp页面的地址:

HTTP Status 404 - /ssmhxweb/WEB-INF/jsp/items/itemsLists.jsp

type Status report

message /ssmhxweb/WEB-INF/jsp/items/itemsLists.jsp

description The requested resource is not available.

--------------------------------------------------------------------------------

Apache Tomcat/8.0.35

4.非注解的处理器映射器和适配器

5.注金额的处理器和适配器

6.源码分析

6.1.接收请求

调用doDispatch方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

HttpServletRequest processedRequest = request;

HandlerExecutionChain mappedHandler = null;

boolean multipartRequestParsed = false;

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {

ModelAndView mv = null;

Exception dispatchException = null;

try {

processedRequest = checkMultipart(request);

multipartRequestParsed = (processedRequest != request);

// Determine handler for the current request.

mappedHandler = getHandler(processedRequest);

if (mappedHandler == null || mappedHandler.getHandler() == null) {

noHandlerFound(processedRequest, response);

return;

}

// Determine handler adapter for the current request.

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

6.2 前端控制器调用处理器映射器 得到 Handler

// Determine handler for the current request.

mappedHandler = getHandler(processedRequest);

/**

* Return the HandlerExecutionChain for this request.

* <p>Tries all handler mappings in order.

* @param request current HTTP request

* @return the HandlerExecutionChain, or {@code null} if no handler could be found

*/

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

for (HandlerMapping hm : this.handlerMappings) {

if (logger.isTraceEnabled()) {

logger.trace(

"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");

}

HandlerExecutionChain handler = hm.getHandler(request);

if (handler != null) {

return handler;

}

}

return null;

}

6.3 调用处理器适配器执行 Handler,得到执行结果 ModelAndView

// Actually invoke the handler.

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

6.4 视图渲染,将 model数据填充到 request 域

1.入口

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

render(mv, request, response);

* Handle the result of handler selection and handler invocation, which is

* either a ModelAndView or an Exception to be resolved to a ModelAndView.

*/

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,

HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {

boolean errorView = false;

if (exception != null) {

if (exception instanceof ModelAndViewDefiningException) {

logger.debug("ModelAndViewDefiningException encountered", exception);

mv = ((ModelAndViewDefiningException) exception).getModelAndView();

}

else {

Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);

mv = processHandlerException(request, response, handler, exception);

errorView = (mv != null);

}

}

// Did the handler return a view to render?

if (mv != null && !mv.wasCleared()) {

render(mv, request, response);

if (errorView) {

WebUtils.clearErrorRequestAttributes(request);

}

}

else {

if (logger.isDebugEnabled()) {

logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +

"': assuming HandlerAdapter completed request handling");

}

}

if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {

// Concurrent handling started during a forward

return;

}

if (mappedHandler != null) {

mappedHandler.triggerAfterCompletion(request, response, null);

}

}

2.视图渲染

render(mv, request, response);

protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {

// Determine locale for request and apply it to the response.

Locale locale = this.localeResolver.resolveLocale(request);

response.setLocale(locale);

View view;

if (mv.isReference()) {

// We need to resolve the view name.

view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);

if (view == null) {

throw new ServletException("Could not resolve view with name '" + mv.getViewName() +

"' in servlet with name '" + getServletName() + "'");

}

}

else {

// No need to lookup: the ModelAndView object contains the actual View object.

view = mv.getView();

if (view == null) {

throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +

"View object in servlet with name '" + getServletName() + "'");

}

}

// Delegate to the View object for rendering.

if (logger.isDebugEnabled()) {

logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");

}

try {

if (mv.getStatus() != null) {

response.setStatus(mv.getStatus().value());

}

view.render(mv.getModelInternal(), request, response);

}

catch (Exception ex) {

if (logger.isDebugEnabled()) {

logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +

getServletName() + "'", ex);

}

throw ex;

}

}

3.视图解析得到view

// We need to resolve the view name.

view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);

//4.填充数据数据

view.render(mv.getModelInternal(), request, response);

//5.填充实现

renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);

@Override

protected void renderMergedOutputModel(

Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

// Expose the model object as request attributes.

exposeModelAsRequestAttributes(model, request);

// Expose helpers as request attributes, if any.

exposeHelpers(request);

//6.具体填充

exposeModelAsRequestAttributes(model, request);

/**

* Expose the model objects in the given map as request attributes.

* Names will be taken from the model Map.

* This method is suitable for all resources reachable by {@link javax.servlet.RequestDispatcher}.

* @param model Map of model objects to expose

* @param request current HTTP request

*/

protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception {

for (Map.Entry<String, Object> entry : model.entrySet()) {

String modelName = entry.getKey();

Object modelValue = entry.getValue();

if (modelValue != null) {

request.setAttribute(modelName, modelValue);

if (logger.isDebugEnabled()) {

logger.debug("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName() +

"] to request in view with name '" + getBeanName() + "'");

}

}

else {

request.removeAttribute(modelName);

if (logger.isDebugEnabled()) {

logger.debug("Removed model object '" + modelName +

"' from request in view with name '" + getBeanName() + "'");

}

}

}

}

5.小结

1.通过入门程序 掌握 springmvc前端控制器、处理器映射器、处理器适配器、视图解析器的执行流程,最好多看源码。

前端控制器url配置

1.*.action

2./

处理器映射器

非注解的处理器映射器

注解的处理器映射器

利用组件扫描来完成

@Controller @RequestMapping

不用在xml中配置url 和 Handler的映射关系。

处理器适配器

非注解的处理器适配器

注解的处理器适配器

注解的处理器适配器和注解的处理器映射器是配对使用的。

<!-- 使用组件扫描 Controller -->

<context:component-scan base-package="org.hxweb.web.ssm.controller"></context:component-scan>

<!-- 实际开发中使用用 mvc:annotation-driven 不用配置注解映射器和注解的适配器,注解的映射器和注解的适配器必须配对使用-->

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

视图解析器

<!-- 配置视图解析器 :InternalResourceViewResolver视图解析器,是解析jsp的视图解析器,默认支持jstl标签 需要有jstl的jar包-->

<!-- 配置视图解析器 :InternalResourceViewResolver视图解析器,是解析jsp的视图解析器,默认支持jstl标签 需要有jstl的jar包-->

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->

<property name="viewClass"

value="org.springframework.web.servlet.view.JstlView" />

<property name="prefix" value="/WEB-INF/jsp/" />

<property name="suffix" value=".jsp" />

</bean>

Handler 中不用指定前缀和后缀,代码简洁。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码