(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~
springmvc基础知识
文章目录
0.课程安排
0.1第一天:springmvc的基础知识
0.1.1什么是springmvc?
(1)springmvc框架原理(掌握)
前端控制器、处理器映射器、处理器适配器、视图解析器
(2)springmvc入门程序
(3)目的:对前端控制器、处理器映射器、处理器适配器、视图解析器学习、非注解的处理器映射器、处理器适配器、注解的处理器映射器、处理器适配器(掌握)
(4)springmvc和mybatis整合(掌握)
(5)springmvc注解开发:(掌握)
- 常用的注解学习
- 参数绑定(简单类型、pojo、集合类型(明天讲))
- 自定义参数绑定(掌握)
0.1.2springmvc和struts2区别
0.2第二天:springmvc的高级应用
0.2.1参数绑定(集合类型)
0.2.2数据回显
0.2.3上传图片
0.2.4json数据交互
0.2.5RESTful支持
0.2.6拦截器
1.springmvc框架
1.1什么是springmvc
(1)springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。
(2)springmvc是一个基于mvc的web框架。
设计模式是总结了我们日常开发中一些很好的经验和编写代码的方法,把它抽取成一种模式,让软件工程师按照这种模式去开发。
1.2 mvc在b/s系统 下的应用
1.3 springmvc框架
(1)第一步,发起请求到前端控制器(Disp
(2)第二步,前端控制器请求HandlerMapping查找Handler.可以根据xml配置、注解进行查找
(3)第三步,处理器映射器HandlerMapping向前端控制器返回Handler.
(4)第四步,前端控制器调用处理器适配器去执行Handler
(5)第五步,处理器适配器去执行Handler
(6)第六步,Handler执行完成给适配器返回ModelAndView
(7)第七步,处理器适配器向前端控制器返回ModelAndView,ModelAndView是springmvc框架的一个底层对象包括了Model和View
(8)前端控制器请求视图解析器去进行视图解析。根据逻辑视图名解析成真正的视图(jsp)。
(9)视图解析器向前端控制器返回View
(10)前端控制器进行视图渲染,视图渲染将模型数据(在ModelAndView对象中)填充到request域。
(11)前端控制器向用户响应结果
组件:
(1)前端控制器:DispatcherServlet(不需要程序员开发)
作用:接收请求,响应结果,相当于转发器,中央处理器。有了DispatcherServlet减少了其他组件之间的耦合度。
(2)处理器映射器:HandlerMapping(不需要程序员开发)
作用:根据请求的url查找Handler
(3)处理器适配器:HandlerAdapter
作用:按照特定规则(HandlerAdpater要求的规则)去执行Handler
(4)处理器Handler(需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler
(5)视图解析器 view resolver(不需要程序员开发)
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)。
(6)视图view(需要程序员开发jsp)
View是一个接口,实现类支持不同的view类型(jsp、freemaker,)
2.入门程序
2.1需求
(1)以案例作为驱动。
(2)springmvc和mybaits使用一个案例(商品订单管理)。
功能需求:商品列表查询
2.2环境准备
(1)数据库环境:mysql5.1
(2)java环境:
-
jdk1.7.0_72
-
eclipse indigo
-
springmvc版本:spring4.2.6
(3)需要spring4.2所有jar(一定包括spring-webmvc-4.2.6.RELEASE.jar)
(4)spring各版本jar包和资源
-
spring历史版本源码:https://github.com/spring-projects/spring-framework/tags
-
spring历史jar包和参考文档(下载有dist的):
https://repo.spring.io/release/org/springframework/spring/
2.3配置前端控制器
在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_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>spmybatis</display-name>
<!-- 1.springmvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--
1.1contextConfigLocation:配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
1.2如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml)
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
1.3: *.action访问以.action结尾,由DispatcherServlet进行解析
1.4: /,所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析
使用此种方法可以实现RestFul风格的url
1.5: /*,这样配置不对,使用这种配置,最终需要转发到一个jsp页面时,仍然会由DispatcherServlet进行解析jsp,不能根据jsp页面找到Handler,会报错。
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.4配置处理器适配器
(1)在classpath下的springmvc.xml中配置处理器适配器
通过查看源代码:
@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;
}
2.5开发Handler
需要实现 controller接口,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter适配器执行。
public class ItemsController1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//1.调用Service查找数据库,查询商品列表,这里使用静态数据模拟
List<Items> itemsList = new ArrayList<Items>();
//2.向list中填充静态数据
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad 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);
//3.返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
//4.相当于request的setAttribute,在jsp页面中通过itemsList取数据
modelAndView.addObject("itemsList",itemsList);
//5.指定视图
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
}
2.6视图编写
2.7配置Handler
目的:将编写Handler在spring容器加载。
<bean name="/queryItems.action" class="com.gdc.ssm.controller.ItemsController1" />
2.8配置处理器映射器
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
2.9配置视图解析器
需要配置解析jsp的视图解析器
<!--
4.视图解析器
解析jsp视图,默认使用jstl标签,classpath下面得有jstl包
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
2.10部署调试
(1)访问地址:
http://localhost:8080/spmybatis/queryItems.action
(2)处理器映射器根据url找不到Handler,报下边的错误。说明url错误。
(3)处理器映射器根据url找到了Handler,转发的jsp页面找到,报下边的错误,说明jsp页面地址错误了。
3非注解的处理器映射器和适配器
3.1非注解的处理器映射器
(1)处理器映射器
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
(2)另一个映射器
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!--
(1)对itemsController1进行url映射,url是/queryItems1.action
(2)同一个ben可以有多个url
-->
<prop key="/queryItems1.action">itemsController1</prop>
<prop key="/queryItems2.action">itemsController1</prop>
</props>
</property>
</bean>
(3)多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。
3.2非注解的处理器适配器
3.2.1SimpleControllerHandlerAdapter
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
(1)要求编写的Handler实现 Controller接口。
3.2.2HttpRequestHandler
<!--
3.2另一个非注解的处理器适配器
-->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
要求编写的Handler实现HttpRequestHandler接口。
/**
* 实现HttpRequestHandler接口的处理器
*/
public class ItemsController2 implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.调用Service查找数据库,查询商品列表,这里使用静态数据模拟
List<Items> itemsList = new ArrayList<Items>();
//2.向list中填充静态数据
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad 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);
//3.设置模型数据
request.setAttribute("itemsList", itemsList);
//4.设置转发的视图
request.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(request, response);
//从上边可以看出此适配器器的handleRequest方法没有返回ModelAndView,可通过response修改定义响应内容,比如返回json数据:
/*response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");*/
}
}
从上边可以看出此适配器器的handleRequest方法没有返回ModelAndView,可通过response修改定义响应内容,比如返回json数据:
response.setCharacterEncoding(“utf-8”);
response.setContentType(“application/json;charset=utf-8”);
response.getWriter().write(“json串”);
4DispatcherSerlvet.properties
前端控制器从上边的文件中加载处理器映射器、适配器、视图解析器等组件,如果不在springmvc.xml中配置,则使用默认加载的。
5.注解的处理器映射器和适配器
(1)在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。
(2)在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器
(3)在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。
(4)在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。
5.1配置注解映射器和适配器。
<!-- 2.2注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--
3.2另一个非注解的处理器适配器
-->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
<!--
4.使用 mvc:annotation-driven代替上边注解映射器和注解适配器的配置
4.1mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
4.2实际开发时使用mvc:annotation-driven
-->
<!-- <mvc:annotation-driven></mvc:annotation-driven> -->
5.2开发注解Handler
(1)使用注解的映射器和注解的适配器。(注解的映射器和注解的适配器必须配对使用)
/**
* 注解开发Handler
* (1)使用@Controller来标识它是一个控制器
*/
@Controller
public class ItemsController3{
/**
* 查询商品列表
* @RequestMapping实现对queryItems方法和url进行映射,一个方法对应一个url.
* 一般建议映射名称与方法名写得一样,为的是方便维护
* @return
* @throws Exception
*/
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws Exception{
//1.调用Service查找数据库,查询商品列表,这里使用静态数据模拟
List<Items> itemsList = new ArrayList<Items>();
//2.向list中填充静态数据
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad 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);
//3.返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
//4.相当于request的setAttribute,在jsp页面中通过itemsList取数据
modelAndView.addObject("itemsList",itemsList);
//5.指定视图
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
//可以在这个类中定义其他的方法了
}
5.3在spring容器中加载Handler
<!--
1.3对于注解的Handler可以单独配置
1.3.1在实际开发中建议使用组件扫描
-->
<!-- <bean class="com.gdc.ssm.controller.ItemsController3"/> -->
<!--
1.3.2可以扫描controller,Service...
1.3.2.1这里扫描controller,指定controller的包
-->
<context:component-scan base-package="com.gdc.ssm.controller"></context:component-scan>
5.4部署调试
访问:
http://localhost:8080/spmybatis/queryItems.action
6源码分析(了解)
通过前端控制器源码分析springmvc的执行过程。
(1)第一步:前端控制器接收请求
调用doDiapatch
(2)第二步:前端控制器调用处理器映射器查找 Handler
(3)第三步:调用处理器适配器执行Handler,得到执行结果ModelAndView
(4)第四步:视图渲染,将model数据填充到request域。
视图解析,得到view:
调用view的渲染方法,将model数据填充到request域
渲染方法:
7入门程序小结
(1)通过入门程序理解springmvc前端控制器、处理器映射器、处理器适配器、视图解析器用法。
7.1前端控制器配置
(1)第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析
(2)第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析
使用此种方式可以实现 RESTful风格的url
7.2处理器映射器
(1)非注解处理器映射器(了解)
(2)注解的处理器映射器(掌握)
对标记@Controller类中标识有@RequestMapping的方法进行映射。在@RequestMapping里边定义映射的url。使用注解的映射器不用在xml中配置url和Handler的映射关系。
7.3处理器适配器
(1)非注解处理器适配器(了解)
(2)注解的处理器适配器(掌握)
注解处理器适配器和注解的处理器映射器是配对使用。理解为不能使用非注解映射器进行映射。
mvc:annotation-driven</mvc:annotation-driven>可以代替下边的配置:
<!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
实际开发使用:mvc:annotation-driven
视图解析器配置前缀和后缀:
<!--
5.视图解析器
解析jsp视图,默认使用jstl标签,classpath下面得有jstl包
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 5.1配置jsp路径的前辍 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 5.2配置jsp路径的后辍 -->
<property name="suffix" value=".jsp"/>
</bean>
程序中不用指定前缀和后缀:
/*
* 5.指定视图
* 5.1下边的路径,如果在视图解析器中配置jsp路径的前辍和jsp路径的后辍,修改为
* modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
* 5.2上面的路径配置可以不在程序中指定jsp路径的前辍和jsp路径的后辍
*/
modelAndView.setViewName("items/itemsList");
8springmvc和mybatis整合
8.1需求
(1)使用springmvc和mybatis完成商品列表查询。
8.2整合思路
(1)springmvc+mybaits的系统架构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XVL84REW-1604042001614)(./c1_17.png)]
8.2.1第一步:整合dao层
(1)mybatis和spring整合,通过spring管理mapper接口。
(2)使用mapper的扫描器自动扫描mapper接口在spring中进行注册。
8.2.2第二步:整合service层
(1)通过spring管理 service接口。
(2)使用配置方式将service接口配置在spring配置文件中。
(3)实现事务控制。
8.2.3第三步:整合springmvc
(1)由于springmvc是spring的模块,不需要整合。
8.3准备环境
(1)数据库环境:mysql5.1
(2)java环境:
-
jdk1.7.0_72
-
eclipse indigo
-
springmvc版本:spring4.2.6
(3)所需要的jar包
- 数据库驱动包:mysql5.1
- mybatis的jar包
- mybatis和spring整合包
- log4j包
- dbcp数据库连接池包
- 需要spring4.2所有jar
- jstl包
(4)工程结构:
8.4整合dao
mybatis和spring进行整合。
8.4.1sqlMapConfig.xml
mybatis自己的配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 1.全局setting配置,根据需要添加 -->
<!-- 2.配置别名 -->
<typeAliases>
<!--
s1.批量别名的定义
指定包名,mybatis会自动的扫描包中的po类,自动定义别名,别名是什么呢?别名就是类名,(首字母大小或小写都可以)
-->
<package name="com.gdc.ssm.po"/>
</typeAliases>
<!--
s2.加载映射文件
由于使用spring和mybatis的整合包进行mapper扫描,这里就不需要配置了。
必须遵循:mapper.xml和mapper.java文件同名且在一个目录
-->
<!--
<mappers>
</mappers>
-->
</configuration>
8.4.2applicationContext-dao.xml
配置:
(1)数据源
(2)SqlSessionFactory
(3)mapper扫描器
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!-- 1.加载db.properties文件中的内容,db.properties文件中的key命名要有一定的特殊规则 -->
<context:property-placeholder
location="classpath:db.properties" />
<!-- 2.配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>
<!-- 3.sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- s3.1.1数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- s3.1.2加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"/>
</bean>
<!--
4.mapper扫描器
4.1从mapper包中扫描出mapper接口,自动创建代理对象并且在spring容器中注册
4.2需要遵循一些规范:
(1)需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录。
4.3自动扫描出来的mapper的bean的id为mapper类名(首字母小写)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--
4.3.1指定扫描的包名
4.3.1.1如果扫描多个包,每个包中间使用半角逗号分隔
-->
<property name="basePackage" value="com.gdc.ssm.mapper"/>
<!-- 使用sqlSessionFactoryBeanName是为了保证先创建数据源 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
8.4.3逆向工程生成po类及mapper(单表增删改查)
将生成的文件拷贝至工程中。
8.4.4手动定义商品查询mapper
针对综合查询mapper,一般情况会有关联查询,建议自定义mapper
8.4.4.1ItemsMapperCustom.xml
sql语句:
SELECT * FROM items WHERE items.name LIKE ‘%笔记本%’
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.gdc.ssm.mapper.ItemsMapperCustom" >
<!-- 1.定义商品查询的sql片段,就是商品的查询条件 -->
<sql id="query_items_where">
<!--
1.1使用动态sql,通过if判断,满足条件进行sql拼接
1.2商品的查询条件,是要通过ItemsQueryVo包装对象中的itemsCustom属性传递
-->
<if test="null!=itemsCustom">
<if test="null!=itemsCustom.name and '' != itemsCustom.name">
items.name LIKE '%${itemsCustom.name}%'
</if>
</if>
</sql>
<!--
2.商品列表查询
2.1parameterType传入包装对象(包装了查询条件)
2.2resultType建立使用扩展对象
-->
<select id="findItemsList" parameterType="com.gdc.ssm.vo.ItemsQueryVo" resultType="com.gdc.ssm.po.ItemsCustom">
SELECT * FROM items
<where>
<include refid="query_items_where"></include>
</where>
</select>
</mapper>
8.4.4.2ItemsMapperCustom.java
public interface ItemsMapperCustom {
/**
* 1.商品列表查询
* @param itemsQueryVo
* @return
* @throws Exception
*/
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;
}
8.5 整合service
让spring管理service接口。
8.5.1定义service接口
public interface ItemsService {
/**
* 商品查询列表
* @param itemsQueryVo
* @return
* @throws Exception
*/
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;
}
public class ItemsServiceImpl implements ItemsService {
@Autowired
private ItemsMapperCustom itemsMapperCustom;
@Override
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception {
//通过ItemsMapperCustom查询数据库
return itemsMapperCustom.findItemsList(itemsQueryVo);
}
}
8.5.2在spring容器配置service(applicationContext-service.xml)
(1)创建applicationContext-service.xml,文件中配置service。
<!-- 商品管理的service -->
<bean id="itemsService" class="com.gdc.ssm.service.impl.ItemsServiceImpl"/>
8.5.3事务控制(applicationContext-transaction.xml)
(1)在applicationContext-transaction.xml中使用spring声明式事务控制方法。
<!--
1.事务管理器
1.1对mybatis操作数据库事务控制,spring使用jdbc的事务控制类.
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--
1.1.1数据源
1.1.1.1dataSource在applicationContext-dao.xml文件中配置了
-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 2.通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 2.1传播行为 -->
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 3.谁去调用通知呢,aop -->
<aop:config >
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.gdc.ssm.service.impl.*.*(..))"/>
</aop:config>
8.6整合springmvc
8.6.1springmvc.xml
(1)创建springmvc.xml文件
(2)配置处理器映射器
(3)配置适配器
(4)配置视图解析器
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!--
1.组件扫描
1.1可以扫描controller,Service...
1.2这里扫描controller,指定controller的包
-->
<context:component-scan base-package="com.gdc.ssm.controller"></context:component-scan>
<!--
2.使用 mvc:annotation-driven代替上边注解映射器和注解适配器的配置
2.1mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
2.2实际开发时使用mvc:annotation-driven
-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--
3.视图解析器
3.1解析jsp视图,默认使用jstl标签,classpath下面得有jstl包
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 3.1配置jsp路径的前辍 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 3.2配置jsp路径的后辍 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
8.6.2配置前端控制器
参考入门程序。
8.6.3编写Controller(就是Handler)
@Controller
public class ItemsController {
@Autowired
private ItemsService itemsService;
/**
* 查询商品列表
* @RequestMapping实现对queryItems方法和url进行映射,一个方法对应一个url.
* 一般建议映射名称与方法名写得一样,为的是方便维护
* @return
* @throws Exception
*/
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws Exception{
//1.调用Service查找数据库,查询商品列表,这里使用静态数据模拟
List<ItemsCustom> itemsList = itemsService.findItemsList(null);
//2.返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
//3.相当于request的setAttribute,在jsp页面中通过itemsList取数据
modelAndView.addObject("itemsList",itemsList);
/*
* 4.指定视图
* 4.1下边的路径,如果在视图解析器中配置jsp路径的前辍和jsp路径的后辍,修改为
* modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
* 4.2上面的路径配置可以不在程序中指定jsp路径的前辍和jsp路径的后辍
*/
modelAndView.setViewName("items/itemsList");
return modelAndView;
}
}
8.6.4编写jsp
8.7加载spring容器
(1)将mapper、service、controller加载到spring容器中。
(2)建议使用通配符加载上边的配置文件。
(3)在web.xml中,添加spring容器监听器,加载spring容器。
9商品修改功能开发
9.1需求
操作流程:
(1)进入商品查询列表页面
(2)点击修改,进入商品修改页面,页面中显示了要修改的商品(从数据库查询)
要修改的商品从数据库查询,根据商品id(主键)查询商品信息
(3)在商品修改页面,修改商品信息,修改后,点击提交
9.2开发mapper
mapper:
(1)根据id查询商品信息
(2)根据id更新Items表的数据
不用开发了,使用逆向工程生成的代码。
9.3开发service
接口功能:
(1)根据id查询商品信息
(2)修改商品信息
9.4开发controller
方法:
(1)商品信息修改页面显示
(2)商品信息修改提交
/**
* 根据id查询商品信息
* @param id 查询商品的id
* @return
* @throws Exception
*/
public ItemsCustom findItemsById(Integer id) throws Exception;
/**
* 修改商品信息
* @param id 要修改商品的id
* @param itemsCustom 修改的商品信息
* @throws Exception
*/
public void updateItems(Integer id,ItemsCustom itemsCustom) throws Exception;
10 @RequestMapping
10.1url映射
定义controller方法对应的url,进行处理器映射使用。
10.2窄化请求映射
@Controller
/**
* 1.为了对url进行分类管理,可以在这里定义根路径,最终访问url是根路径+子路径
* 1.1比如商品列表:/itms/queryItems.action
*/
@RequestMapping("/items")
public class ItemsController {
10.3限制http请求方法
(1)出于安全性考虑,对http的链接进行方法限制。
(2)如果限制请求为post方法,进行get请求,报错:
/**
* 商品信息修改页面显示
* 1.@RequestMapping("/editItems")
* 2.限制http请求的方法,可以是get和post
* @return
* @throws Exception
*/
@RequestMapping(value="/editItems",method= {RequestMethod.GET,RequestMethod.POST})
11.controller方法的返回值
11.1返回ModelAndView
需要方法结束时,定义ModelAndView,将model和view分别进行设置。
11.2返回string
如果controller方法返回string,
(1)表示返回逻辑视图名。
真正视图(jsp路径)=前缀+逻辑视图名+后缀
@RequestMapping(value="/editItems",method= {RequestMethod.GET,RequestMethod.POST})
public String editItems(Model model) throws Exception{
//1.调用service根据商品id查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(1);
//2.通过形参中的Model将model数据传到页面,相当于addObject("itemsCustom", itemsCustom);
model.addAttribute("itemsCustom", itemsCustom);
return "items/editItems";
}
(2)redirect重定向
- 商品修改提交后,重定向到商品查询列表。
- redirect重定向特点:浏览器地址栏中的url会变化。修改提交的request数据无法传到重定向的地址。因为重定向后重新进行request(request无法共享)
return "redirect:queryItems.action";
(3)forward页面转发
通过forward进行页面转发,浏览器地址栏url不变,request可以共享。
return "forward:queryItems.action";
11.3返回void
在controller方法形参上可以定义request和response,使用request或response指定响应结果:
(1)使用request转向页面,如下:
request.getRequestDispatcher("页面路径").forward(request, response);
(2)也可以通过response页面重定向:
response.sendRedirect("url")
(3)也可以通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
12参数绑定
12.1spring参数绑定过程
(1)从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。
(2)springmvc中,接收页面提交的数据是通过方法形参来接收。而不是在controller类定义成员变量接收!!!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NFpCMjD4-1604042001625)(./c1_24.png)]
12.2默认支持的类型
直接在controller方法形参上定义下边类型的对象,就可以使用这些对象。在参数绑定过程中,如果遇到下边类型直接进行绑定。
12.2.1HttpServletRequest
通过request对象获取请求信息
12.2.2HttpServletResponse
通过response处理响应信息
12.2.3HttpSession
通过session对象得到session中存放的对象
12.2.4Model/ModelMap
12.3简单类型
(1)通过@RequestParam对简单类型的参数进行绑定。
(2)如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功。
(3)如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致。
(4)通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:
(5)如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致。
(6)通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:
(7)参考教案 对其它简单类型绑定进行测试。
12.4pojo绑定
(1)页面中input的name和controller的pojo形参中的属性名称一致,将页面中数据绑定到pojo。
(2)页面定义:
<tr>
<td>商品名称</td>
<td><input type="text" name="name" value="${itemsCustom.name }"/></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="price" value="${itemsCustom.price }"/></td>
</tr>
(3)controller的pojo形参的定义:
public class Items {
private Integer id;
private String name;
private Float price;
12.5自定义参数绑定实现日期类型绑定
(1)对于controller形参中pojo对象,如果属性中有日期类型,需要自定义参数绑定。
(2)将请求日期数据串传成日期类型,要转换的日期类型和pojo中日期属性的类型保持一致。
public class Items {
private Integer id;
private String name;
private Float price;
private String pic;
private Date createtime;
private String detail;
(3)所以自定义参数绑定将日期串转成java.util.Date类型。
(4)需要向处理器适配器中注入自定义的参数绑定组件。
12.5.1自定义日期类型绑定
public class CustomDateConverter implements Converter<String, Date>{
@Override
public Date convert(String source) {
//s1.实现将日期串转换成日期类型(格式是:yyyy-MM-dd HH:mm:ss)
SimpleDateFormat sp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
//s2.转成功直接返回
return sp.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
//s3.如果参数绑定失败则返回null
return null;
}
}
12.5.2配置方式
<!--
2.使用 mvc:annotation-driven代替上边注解映射器和注解适配器的配置
2.1mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
2.2实际开发时使用mvc:annotation-driven
-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 4.自定义参数绑定 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 4.1自定义参数转换器 -->
<property name="converters">
<!--4.1.1自定义日期转换器 -->
<list>
<bean class="com.gdc.ssm.controller.converter.CustomDateConverter"/>
</list>
</property>
</bean>
13springmvc和struts2的区别
(1)springmvc基于方法开发的,struts2基于类开发的。
-
springmvc将url和controller方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。
-
方法执行结束,形参数据销毁。
-
springmvc的controller开发类似service开发。
解说: -
springmvc参数都通过形参来接,你会发现参数只应用于单个方法。所以它更接近于service的开发。
-
struts2随着方法的增加,里面有很多的成员变量,维护到最后,根本不知道这个变量被哪个方法用。
(2)springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。
(3)经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。
14.问题
14.1post请求乱码问题
(1)在web.xml添加post乱码filter
(2)在web.xml中加入:
<!-- 2.解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
14.2get请求乱码问题
对于get请求中文参数出现乱码解决方法有两个:
(1)修改tomcat配置文件添加编码与工程编码一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
(2)另外一种方法对参数进行重新编码:
String userName new
String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码