Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,能够选择使用Spring的SpringMVC框架或集成其余MVC开发框架,如Struts1(如今通常不用),Struts2等。javascript
---------百度百科前端
从spring官网中能够看出,Spring MVC原名叫Spring Web MVC,它是构建在Servlet API上的最初的Web框架,从一开始就包含在Spring框架中。正式名称“Spring Web MVC”来自其源模块spring-webmvc的名称, 但它一般被称为“Spring MVC”。Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分。java
从请求中接收传入的参数,将处理后的结果返回给页面展现mysql
1)、 用户发送请求至前端控制器DispatcherServletjquery
2)、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。nginx
3)、 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(若是有则生成)一并返回给DispatcherServlet。git
4)、 DispatcherServlet经过HandlerAdapter处理器适配器调用处理器github
5)、 执行处理器(Controller,也叫后端控制器)。web
6)、 Controller执行完成返回ModelAndViewajax
7)、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8)、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9)、 ViewReslover解析后返回具体View
10) DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11) DispatcherServlet响应用户
需求:显示商品列表
jar包下载地址:springMVC_jar
若是是maven。其相关依赖为
<dependencies> <dependency> <!--使用Junit4,采用注解形式 --> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> <!--配置maven工做范围:由于驱动只有真正工做时才会启动 --> <scope>runtime</scope> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>provided</scope> </dependency> <!--spring依赖 --> <!--1.spring核心依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.7.RELEASE</version> </dependency> <!--2.spring Dao层依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.1.7.RELEASE</version> </dependency> <!--3.spring web相关依赖:用于当启动服务器时加载配置文件 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.7.RELEASE</version> </dependency> <!--用于springMVC须要 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.1.7.RELEASE</version> </dependency> <!--4.spring test测试相关依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.1.7.RELEASE</version> </dependency> </dependencies>
导入相应地约束
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> </beans>
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
ItemController是一个普通的java类,不须要实现任何接口,只须要在类上添加@Controller注解便可。@RequestMapping注解指定请求的url,其中“.action”能够加 也能够不加。注意:1.这里的配置@Controller注解 2.@RequestMapping用于识别域名后缀 3.modelAndView.setViewName用于设置跳转页面
// 在添加注解的同时,还得配置扫描 @Controller public class ItemsController { //指定url到请求方法的映射 //url中输入一个地址,例如:localhost:8888/SpringMvc/list.action //用以替代了struts中采用的配置文件进行匹配来调用那个方法从而识别跳转那个页面 @RequestMapping("/list") public ModelAndView itemsList()throws Exception{ List<Items> itemList = new ArrayList<Items>(); //商品列表 Items items_1 = new Items(); items_1.setName("联想笔记本_3"); 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苹果手机!"); itemList.add(items_1); itemList.add(items_2); //模型视图 //model模型:模型对象中存放了返回给页面的数据 //view视图:视图对象中指定给返回的页面的位置 //建立modelandView对象 ModelAndView modelAndView = new ModelAndView(); //添加model(将返回给页面的数据放入模型和视图对象中) modelAndView.addObject("itemList", itemList); //添加视图(指定给 返回页面的位置) modelAndView.setViewName("jsp/itemList.jsp"); return modelAndView; } }
这里controller类是建立在cn.clj.controller包下的
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.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.xsd"> <context:component-scan base-package="com.clj.controller"/> <mvc:annotation-driven></mvc:annotation-driven> </beans>
注意:指定核心配置文件名不能写错,不然会找不到Controller类
<!-- springMvc前端控制器 --> <servlet> <servlet-name>springMvc</servlet-name> <!--路径:spring-webmvc-4.1.3.RELEASE.jar\org.springframework.web.servlet --> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 若是没有指定springMvc核心配置文件那么默认会去找/WEB_INF/+<servlet-name>的内容+ -servlet.xml配置文件 --> <!-- 指定springMvc核心配置文件位置 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMvc.xml</param-value> </init-param> <!-- tomcat启动时就加载这个servlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
DispatcherServlet的路径为:
在WebRoot下建立jsp文件夹,用来存放jsp
1.需引入jstl标签 2.由于传的是itemList,接收值不能写错
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<body> <form action="${pageContext.request.contextPath }/search.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <!-- 若是controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--> <td>商品名称:<input type="text" name="items.name"/></td> <td>商品价格:<input type="text" name="items.price"/></td> <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="${itemList}" 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 }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>
此时在浏览器中输入http://localhost:8080/项目名/list.action,若是成功跳转到显示页面为成功
注解式处理器映射器:注解式处理器映射器,对类中标记@ResquestMapping的方法进行映射,根据ResquestMapping定义的url匹配ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装url对应的方法Method。
注解式处理器适配器:注解式处理器适配器,对标记@ResquestMapping的方法进行适配。
方式一:手动配置最新版本的映射器和适配器(缺点:随着版本更新的从新配置)
<!-- 配置最新版的注解的处理器映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!-- 配置最新版的注解的处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
方式二:自动配置
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
所有代码以下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.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.xsd">
<!-- 配置@Controller注解扫描 --> <context:component-scan base-package="cn.clj.controller"/> <!-- 若是没有显示配置处理器映射器和处理器适配器那个springMvc会默认的dispatcherServlet.properties中查找 对应的处理器映射器和处理器适配器去使用,每一个请求都要扫描一次的默认配置文件,效率很是低,会下降访问速度,因此显示的配置处理器映射器和处理器适配器 --> <!-- 注解形式的处理器适配器 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> --> <!-- 注解形式的处理器映射器 <bean class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"/>--> <!-- 配置最新版的注解的处理器映射器,以上已通过时 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>--> <!-- 配置最新版的注解的处理器适配器 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>--> <!-- 注解驱动:可以自动配置最新版的处理器映射器和处理器适配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> </beans>
在controller中,每次配置跳转页面时,都要配置跳转视图的所有路径,有点麻烦
功能:在配置文件中配置全局跳转视图的前缀名和后缀名,在controller类只要写省去后缀的jsp名便可,配置以下:
1)在SpringMvc.xml文件中配置视图解析器
<!-- 配置视图解析器 --> <!-- 做用:在controller中指定页面路径的时候就不用写页面的完整路径名称,直接写去掉后缀的页面名 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--真正页面路径=前缀+页面名称+后缀 --> <!-- 跳转视图前缀 --> <property name="prefix" value="/jsp/"></property> <!-- 跳转视图后缀 --> <property name="suffix" value=".jsp"></property> </bean>
2)更改conroller类中的写法
//添加视图(指定给 返回页面的位置) // modelAndView.setViewName("jsp/itemList.jsp"); modelAndView.setViewName("itemList"); return modelAndView;
我的认为,SpringMvc与Mybatis整合其实就是SSM整合,由于Spring与SpringMvc同属于一家公司,无需整合,固然也须要用到Spring的IOC特性业务分配:此时控制层交给SpringMvc,持久层交给MyBatis,建立管理交给Spring
思路:
Dao层:
1、SqlMapConfig.xml,空文件便可。须要文件头。 二、applicationContext-dao.xml。 a) 数据库链接池 b) SqlSessionFactory对象,须要spring和mybatis整合包下的。 c) 配置mapper文件扫描器。
Service层:
一、applicationContext-service.xml包扫描器,扫描@service注解的类。 二、applicationContext-trans.xml配置事务。
表现层:
Springmvc.xml 1、包扫描器,扫描@Controller注解的类。 2、配置注解驱动。 3、视图解析器 Web.xml 配置前端控制器。
1)导入相应的依赖jar包
此包含Mybatis依赖jar包与逆向工程依赖jar包、Spring依赖jar包与Spring-mybatis整合包、SpringMVc依赖包,数据库驱动包,第三方链接池
2)在工程项目下(非src)建立源码包,用来存放配置文件,包名为config
3)建立分层包,采用MVC模式开发,每一个包的业务不一样
4)建立db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://192.168.174.132:3306/SSM jdbc.username=root jdbc.password=root
5)配置log4j.properties
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
6)建立spring核心配置文件之applicationContext-dao.xml
此文件用来管理dao层业务:配置数据源,配置SqlSessionFactory与dao层mapper扫描
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 加载配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 数据库链接池 --> <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> <!-- mapper配置 --> <!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 数据库链接池 --> <property name="dataSource" ref="dataSource"/> <!-- 加载mybatis的全局配置文件 --> <property name="configLocation" value="classpath:SqlMapConfig.xml"/> </bean> <!-- 配置Mapper扫描器 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.clj.dao"/> </bean> </beans>
7)建立spring核心配置文件之applicationContext-service.xml
此文件主要是负责业务层:开启service注解扫描
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- @service扫描 --> <context:component-scan base-package="cn.clj.service"></context:component-scan> </beans>
8)建立spring核心配置文件之applicationContext-transaction.xml
此文件主要负责事务:配置事务管理并注入数据源,配置事务通知与切面
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- 通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 传播行为 --> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="delete*" 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:attributes> </tx:advice> <!-- 切面 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.clj.service.*.*(..))" /> </aop:config> </beans>
9)建立SpringMvc核心配置文件之SpringMvc.xml
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置@Controller注解扫描 --> <context:component-scan base-package="cn.clj.controller"/> <!-- 注解驱动:可以自动配置最新版的处理器映射器和处理器适配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <!-- 配置视图解析器 --> <!-- 做用:在controller中指定页面路径的时候就不用写页面的完整路径名称,直接写去掉后缀的页面名 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--真正页面路径=前缀+页面名称+后缀 --> <!-- 跳转视图前缀 --> <property name="prefix" value="/jsp/"></property> <!-- 跳转视图后缀 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
10)配置服务器启动扫描
整合后以上的配置文件,服务器不能自动识别加载,须要在web.xml文件中开启包扫描
<!-- 开启spring各核心配置文件扫描 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 开启SpringMVc拦截器--> <servlet> <servlet-name>SpringMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置SpringMvc核心配置文件所在路径 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
以上整合环境部署大体完成
需求1:从数据库查询到商品信息,并将数据返回到jsp中
1)开启逆向工程自动生成pojo类和mapper接口和映射文件
1.1: 导入逆向工程jar包mybatis-generator-core-1.3.2
1.2 :在config包下建立generatorConfig.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="testTables" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--数据库链接的信息:驱动类、链接地址、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://192.168.174.132:3306/SSM" userId="root" password="root"> </jdbcConnection> <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --> <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成PO类的位置 --> <javaModelGenerator targetPackage="cn.clj.pojo" targetProject=".\src"> <!-- enableSubPackages:是否让schema做为包的后缀 --> <property name="enableSubPackages" value="false" /> <!-- 从数据库返回的值被清理先后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="cn.clj.dao" targetProject=".\src"> <!-- enableSubPackages:是否让schema做为包的后缀 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="cn.clj.dao" targetProject=".\src"> <!-- enableSubPackages:是否让schema做为包的后缀 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 指定数据库表 --> <table tableName="items"></table> <table tableName="user"></table> <!-- <table schema="" tableName="sys_user"></table> <table schema="" tableName="sys_role"></table> <table schema="" tableName="sys_permission"></table> <table schema="" tableName="sys_user_role"></table> <table schema="" tableName="sys_role_permission"></table> --> <!-- 有些表的字段须要指定java类型 <table schema="" tableName=""> <columnOverride column="" javaType="" /> </table> --> </context> </generatorConfiguration>
1.3:建立启动类
这里须要配置generatorConfig.xml文件所在路径,并运行此类
package cn.clj.start; import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; public class StartGenerator { public void generator() throws Exception{ List<String> warnings = new ArrayList<String>(); boolean overwrite = true; File configFile = new File("config/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } public static void main(String[] args) throws Exception { try { StartGenerator startService = new StartGenerator(); startService.generator(); } catch (Exception e) { e.printStackTrace(); } } }
自动生成的文件
package cn.clj.service; import java.util.List; import cn.clj.pojo.Items; public interface ItemsService { public List<Items> list() throws Exception; }
注意:这里注入了Mapper接口,并开启了自动扫描注解
package cn.clj.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.clj.dao.ItemsMapper; import cn.clj.pojo.Items; import cn.clj.pojo.ItemsExample; @Service public class ItemsServiceImpl implements ItemsService{ @Autowired private ItemsMapper itemsMapper; @Override public List<Items> list() throws Exception { //selectByExampleWithBLOBs(example)包含文本类型 ItemsExample example=new ItemsExample(); //example.createCriteria()能够建立查询条件;若是无需任何查询条件,直接将example实例化便可 List<Items> list=itemsMapper.selectByExampleWithBLOBs(example); return list; } }
@Controller public class ItemController { //注意:这里可使用Autowired:自动装配(缺点:当一个接口有两个实现类时就没法世识别) //Resource:值是取实现类中定义的注解值 @Autowired private ItemsService itemsService; //查询全部 @RequestMapping("/list") public ModelAndView itemsList() throws Exception{ List<Items> list=itemsService.list(); ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("itemList",list); modelAndView.setViewName("itemList"); return modelAndView; } }
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> <body> <form action="${pageContext.request.contextPath }/search.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <!-- 若是controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--> <td>商品名称:<input type="text" name="items.name"/></td> <td>商品价格:<input type="text" name="items.price"/></td> <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="${itemList}" 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 }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form> </body>
1) 使用@RequestParam经常使用于处理简单类型的绑定
如:jsp传入一个值
<input type="text" name="item_id"/>
controller接收
public String editItem(@RequestParam(value="item_id",required=true) String id) { }
注意:
1.1 ) value:参数名字,即入参的请求参数名字,形参名称为id,可是这里使用value="item_id"限定请求的参数名为item_id,因此页面传递参数的名必须为item_id。若是请求参数中没有item_id将跑出异常:
HTTP Status 500 - Required Integer parameter 'item_id' is not present
1.2)这里经过required=true限定item_id参数为必需传递,若是不传递则报400错误,可使用defaultvalue设置默认值,即便required=true也能够不传item_id参数值
需求1:打开编辑界面,查看商品详情
环境:引用以上环境,当触发itemList.jsp中的修改按钮,根据超连接跳转,传入参数为商品id
1)、编写接口和实现类
public Items findItemsById(Integer id) throws Exception
package cn.clj.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.clj.dao.ItemsMapper; import cn.clj.pojo.Items; import cn.clj.pojo.ItemsExample; @Service public class ItemsServiceImpl implements ItemsService{ @Autowired private ItemsMapper itemsMapper; @Override public Items findItemsById(Integer id) throws Exception { Items items=itemsMapper.selectByPrimaryKey(id); return items; } }
2)、编写controller
参数经过域名封装到请求中,此时能够在方法中定义HttpServletRequest、HttpSession、Model将参数得到
注意:这里设置返回页面是个字符串
package cn.clj.controller; import java.util.Date; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import cn.clj.pojo.Items; import cn.clj.service.ItemsService; import cn.clj.vo.QueryVo; @Controller public class ItemController { //注意:这里可使用Autowired:自动装配(缺点:当一个接口有两个实现类时就没法世识别) //Resource:值是取实现类中定义的注解值 @Autowired private ItemsService itemsService;/** * springMvc默认支持的参数类型,也就是说在controller方法中能够加入这些,也能够不加 * HttpServletRequest * HttpServletResponse * HttpSession * Model */ @RequestMapping("/itemEdit") public String itemEdit(HttpServletRequest request,Model model) throws Exception{ String idStr=request.getParameter("id"); Items items=itemsService.findItemsById(Integer.parseInt(idStr)); //Model模型:模型中放入了返回给页面的数据 //Model底层就是用的request域传递数据,可是对request进行了扩展 model.addAttribute("item",items); //若是springMvc方法返回一个简单的string字符串,那么springMvc就会认为这个字符串就是页面的名称 return "editItem"; } }
3)、建立editItem.jsp接受参数
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <body> <!-- 上传图片是须要指定属性 enctype="multipart/form-data" --> <!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> --> <form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post"> <input type="hidden" name="id" value="${item.id }" /> 修改商品信息: <table width="100%" border=1> <tr> <td>商品名称</td> <td><input type="text" name="name" value="${item.name }" /></td> </tr> <tr> <td>商品价格</td> <td><input type="text" name="price" value="${item.price }" /></td> </tr> <tr> <td>商品简介</td> <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea> </td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td> </tr> </table> </form> </body>
绑定pojo类型
需求二、更新数据
1)、前提有pojo类(其中在修改界面中的接受的Items 的属性必须与pojo类中的属性保持一致)
package cn.clj.pojo; 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; //省略set/get方法 }
1)、建立接口和实现类
public void updateItems(Items items) throws Exception;
@Service public class ItemsServiceImpl implements ItemsService{ @Autowired private ItemsMapper itemsMapper; @Override public void updateItems(Items items) throws Exception { // TODO Auto-generated method stub //此方法包含大对象文本 itemsMapper.updateByPrimaryKeyWithBLOBs(items); } }
2)、建立conroller类定义方法
@Controller public class ItemController { //注意:这里可使用Autowired:自动装配(缺点:当一个接口有两个实现类时就没法世识别) //Resource:值是取实现类中定义的注解值 @Autowired private ItemsService itemsService;/** * 更新数据 * @return */ //1.springMvc能够直接接受基本数据类型,包括string,spring Mvc能够帮你自动进行类型转换 //controller方法接受的参数的变量名称必需要等于页面上input框的name属性值 //2.springMvc能够直接接受pojo类型,要求页面上input框的name属性名称必须等于pojo的属性名称 @RequestMapping("/updateitem") public String updateitem(Items items) throws Exception{ //方式二 //public String updateitem(Integer id,String name,Float price,String detail) throws Exception{ //方式一 // Items items=new Items(); // items.setId(id); // items.setName(name); // items.setPrice(price); // items.setDetail(detail); //注意:这里jsp源代码中屏蔽了接受时间的框,是由于String类型能够转换为基本类型,可是string类型不能转换为Date类型 items.setCreatetime(new Date());//数据库字段定义为非空 itemsService.updateItems(items); return "success"; } }
3)、建立success.jsp页面
<body> <h3>更新成功</h3> </body>
解决中文乱码问题
1)针对post请求
post请求是封装于服务器端,请求参数不会在域名中出现
在web.xml中配置过滤器,当服务器启动时就对请求中的参数进行字符编码转换
<!-- 解决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>
2)针对get请求
get请求是响应在地址栏中,经过地址栏能够看到请求参数
将controller类中接受到的包含中文参数进行字符编码转换
String name=new String(request.getAttribute("参数名").getBytes("iso-8859-1"),"utf-8"));
绑定包装类
需求3:使用包装类接受高级查询条件中所传过来的值
1) 定义VO
package cn.clj.vo; import java.util.Arrays; import java.util.List; import cn.clj.pojo.Items; /** * 演示高级查询,封装指定pojo类中的指定属性 * @author 佳先森 * */ public class QueryVo { //商品对象 private Items items;
//省略set/get、toString方法
}
2) 定义jsp
<form action="${pageContext.request.contextPath }/search.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <!-- 若是controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--> <td>商品名称:<input type="text" name="items.name"/></td> <td>商品价格:<input type="text" name="items.price"/></td>
<td><input type="submit" value="查询"/></td> </tr> </table>
3) controller类中定义方法
@Controller public class ItemController { //若是controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用 @RequestMapping("/search") public String search(QueryVo vo) throws Exception{ System.out.println(vo); return ""; }
自定义参数绑定
需求:接受参数为时间格式
分析:为何输入框为时间格式的conroller接收时会报错呢,是由于spring MVC可以将自动将字符串转换为原始型和包装类型,可是它不能讲时间格式的转换为字符串(时间格式有多种),否则会报错,这里只能为时间格式自定义参数绑定
1) 建立工具类
package cn.controller.converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; /** * 自定义全局字符串转日期转换器 * param:s -source:源 * param:T -target:目标 * 还需在springMv中配置此工具类 * @author 佳先森 * */ public class CustomGlobalStrToDateConverter implements Converter<String,Date>{ @Override public Date convert(String source) { try { Date date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source); return date; } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
2) 在SpringMVc上建立自定义转换器,并将它配置到注解驱动上
<!-- 注解驱动:可以自动配置最新版的处理器映射器和处理器适配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <!-- 配置自定义转换器:用于将字符串转换为日期格式 步骤:1.编写工具类 2.将自定义的转换器配置到注解驱动上 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <!-- 指定自定义转换器的全路径名名称 --> <bean class="cn.controller.converter.CustomGlobalStrToDateConverter"/> </set> </property> </bean>
3) jsp界面
注意引入jstl/fmt标签,这是可以在界面中对时间内容进行格式整理
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post"> <table width="100%" border=1> <tr> <td>商品生产日期</td> <td><input type="text" name="createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td> </tr> </table> </form>
4) controller接收方法
@RequestMapping("/updateitem") public String updateitem(Items items,Model model) throws Exception{ itemsService.updateItems(items); return "success"; }
一、 springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
二、 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,能够设计为单例或多例(建议单例),struts2是基于类开发,传递参数是经过类的属性,只能设计为多例。
三、 Struts采用值栈存储请求和响应的数据,经过OGNL存取数据, springmvc经过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据经过reques域传输到页面。Jsp视图解析器默认使用jstl。
需求:演示批量删除
1) 定义jsp
jsp中包含一个form表单,多个input框前有个checkbox复选框
<form action="${pageContext.request.contextPath }/delAll.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <!-- 若是controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--> <td>商品名称:<input type="text" name="items.name"/></td> <td>商品价格:<input type="text" name="items.price"/></td> <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="${itemList}" var="item"> <tr> <!-- 批量删除:name属性名称等于vo中的接受的属性名称 --> <td> <input type="checkbox" name="ids" value="${item.id}"/> </td> <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 }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>
2)定义controller中的方法
这里是经过复选框将选中的数据进行传送,controller方法中得用数组来接收
方式一:数组做为参数进行接收:注意这里属性名(ids)要与复选框保持一致
//若是批量删除,一堆input复选框,那么能够提交数据(只有被选中的时候才能够提交) @RequestMapping("/delAll") public String delAll(String[] ids) throws Exception{ System.out.println(ids.toString()); return ""; }
方式二:将数组做为属性封装到VO对象中,将VO对象做为参数进行接收
public class QueryVo { //商品对象 private Items items; //批量删除 private Integer[] ids; //省略set/get方法 }
//若是批量删除,一堆input复选框,那么能够提交数据(只有被选中的时候才能够提交) @RequestMapping("/delAll") public String delAll(QueryVo vo) throws Exception{ System.out.println(vo.getItems().getName()); System.out.println(queryVo.getItems().getPrice()); return ""; }
二、绑定集合(将表单的数据绑定到List中)
需求:对数据进行批量修改
1) 在pojo类中定义一个集合的属性
package cn.clj.vo; import java.util.Arrays; import java.util.List; import cn.clj.pojo.Items; /** * 演示高级查询,封装指定pojo类中的指定属性 * @author 佳先森 * */ public class QueryVo { //商品对象 private Items items; //用户对象 //。。。。 //批量删除 private Integer[] ids; //批量修改 private List<Items> itemsList; //省略set/get,toString()方法 }
2)更改jsp
<form action="${pageContext.request.contextPath }/updateAll.action" method="post"> 查询条件: <table width="100%" border=1> <tr> <!-- 若是controller接受的是vo,那么页面上input框中name属性值要等于vo属性.属性 (..)进行引用--> <td>商品名称:<input type="text" name="items.name"/></td> <td>商品价格:<input type="text" name="items.price"/></td> <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="${itemList}" var="item" varStatus="status"> <tr> <!-- 若是批量修改,能够用List<pojo>来接受,页面上input框的name属性值=vo中的接受的属性名称+[list的下标]+.+list泛型属性的名称 --> <td> <input type="checkbox" name="ids" value="${item.id}"/> <input type="hidden" name="itemsList[${status.index}].id" value="${item.id}"/> </td> <td><input type="text" name="itemsList[${status.index}].name" value="${item.name}"/></td> <td><input type="text" name="itemsList[${status.index}].price" value="${item.price}"/></td> <td><input type="text" name="itemsList[${status.index}].createtime" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td> <td><input type="text" name="itemsList[${status.index}].detail" value="${item.detail}"/></td> <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td> </tr> </c:forEach> </table> </form>
3)在controller类中建立接受方法
//批量修改 @RequestMapping("/updateAll") public String updateAll(QueryVo vo) throws Exception{ System.out.println(vo.getItems().getName());
System.out.println(vo.getItems().getPrice());
return "";
}
分析:在团队开发状况下,不一样controller中可能出现一个或多个方法RequestMapping值相同,由于配置文件中采用的是包扫描的方法进行映射,就有可能在输入域名的时候跳错controller中的方法。此时,若是为了区分每一个conroller中的每一个方法,必须配置窄化请求映射,至关于给类起个名字,每当反问域名时,指定跳转方法uri前必须加上这个“类名”,经过此方法对类行进分类管理
如:
@Controller //窄化请求映射:为防止方法名重名,至关于在url中多加了一层目录,房子重名 @RequestMapping("/items") public class ItemController { //批量修改 @RequestMapping("/updateAll") public String updateAll(QueryVo vo) throws Exception{ System.out.println(vo); return ""; }
若是之后要跳转到该方法,域名得写成http://localhost:8080/项目名/items/updateAll.action
语法为@RequestMapping(value="/XXX",method=RequestMethod.XX),其中XX能够写GET或者POST,若是在方法中限定了请求方法而jsp中表单提交方式不是指定的,会报405错误
@RequestMapping(value="/list",method=RequestMethod.GET) public ModelAndView itemsList() throws Exception{ List<Items> list=itemsService.list(); System.out.println("进入了"); ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("itemList",list); modelAndView.setViewName("itemList"); return modelAndView; }
controller方法返回值包含多种,一下介绍几种经常使用的:
@RequestMapping(value="/list",method=RequestMethod.GET) public ModelAndView itemsList() throws Exception{ List<Items> list=itemsService.list(); ModelAndView modelAndView=new ModelAndView(); modelAndView.addObject("itemList",list); modelAndView.setViewName("itemList"); return modelAndView; }
种类一:放回普通字符串(去掉页面扩展名)
@RequestMapping("/search") public String search(QueryVo vo) throws Exception{ System.out.println(vo); return "success"; }
种类二:请求转发方式
注意:这里是请求转发跳转到同一个Controller中的注解值为itemEdit的方法,请求转发可以携带值
@RequestMapping("/updateitem") public String updateitem(Items items,Model model) throws Exception{ itemsService.updateItems(items);//请求转发:浏览器中的url不发生改变,request域中的数据能够带到转发后的方法中 model.addAttribute("id",items.getId());//或者:request.setAttribute("id",items.getId()) //springMvc中请求转发:返回的字符串以forward:开头的都是请求转发 return "forward:itemEdit.action"; }
种类三:重定向方式
注意:重定向的方式是不能携带值的,若是要传参数,得封装到域名中(如:return "redirect:itemsEdit.action?id="+items.getId())
@RequestMapping("/updateitem") public String updateitem(Items items,Model model) throws Exception{ itemsService.updateItems(items); model.addAttribute("id",items.getId());//在springMvc中凡是以redirect:字符串开头的的都是重定向 return "redirect:itemsEdit.action"; }
种类三:返回值为void
这里演示的请求请求转发的方式(若是controller方法返回值为void,则不走SpringMvc组件,须要些完整的路径名称))
@RequestMapping("/updateitem") public void updateitem(Items items,HttpServletRequest request,HttpServletResponse response) throws Exception{ itemsService.updateItems(items); request.setAttribute("id",items.getId()) request.getRequestDispatcher("/jsp/success.jsp").forward(request, response);
}
需求:当条件查询询信息时出现错误(没有该商品),都会跳转到指定的错误页面
package cn.clj.vo; public class CustomerException extends Exception{ //异常信息 private String message; public CustomerException(String message) { super(); this.message = message; } //省略set/get方法 }
public class GlobalExceptionResolver implements HandlerExceptionResolver{ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ex.printStackTrace(); CustomerException customerException=null; if(ex instanceof CustomerException){ customerException=(CustomerException) ex; }else{ customerException=new CustomerException("系统错误,请联系管理员"); } ModelAndView model=new ModelAndView(); model.addObject("message",customerException); model.setViewName("error"); return model; } }
<body> 您的操做出现错误以下:<br/>
<h3><font color="red">${message}</font></h3>
</body>
<!-- 异常处理器 -->
<bean id="handlerExceptionResolver" class="cn.clj.vo.CustomerException"/>
</beans>
在调用查询方法时,若是查询到的商品不存在,抛出自定义异常类
@RequestMapping("/itemEdit") public String itemEdit(HttpServletRequest request,Model model) throws Exception{ String idStr=request.getParameter("id"); Items items=itemsService.findItemsById(Integer.parseInt(idStr)); if(items==null){ throw new CustomerException("您查询的信息不存在"); } model.addAttribute("item",items); return "editItem"; }
当查询一个不存在的商品,若是成功跳转到自定义异常界面,表示配置成功
分析:企业中像那种高并发项目,都会有不一样的服务器接受不一样资源,利用nginx实现负载均衡。这里由于只上传图片,服务器只有tomcat,因此只能在tomcat中配置。
此配置就是将上传的图片放置到指定的文件夹下
作法:进入tomcat/conf/server.xml文件中,加入下面一条命令,表示到域名以pic结尾时,访问的目录为E:\壁纸文件夹下
<Context docBase="E:\壁纸" path="/pic" reloadable="false"/>
<!-- 文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
文件上传是经过表单提交的,所提交的是一连串字符串,需对字符串进行处理,这里为了防止所存的图片文件重名,采用了随机字符串进行拼接
//演示上传图片:注意"pictureFile"是与jsp中文件上传属性保持一致 @RequestMapping("/upload") public String upload(MultipartFile pictureFile,Items items,Model model) throws Exception{ //1.获取图片完整名称 String fileStr=pictureFile.getOriginalFilename(); //2.使用随机生成的字符串+源图片扩张名组成新的图片名称,防止图片重名 String newFileName=UUID.randomUUID().toString()+fileStr.substring(fileStr.lastIndexOf(".")); //3.将图片保存到硬盘 pictureFile.transferTo(new File("E:\\壁纸\\"+newFileName)); //4.将图片名称保存到数据库 items.setPic(newFileName); itemsService.updateItems(items); return "success"; }
<form id="itemForm" action="${pageContext.request.contextPath }/upload.action" method="post" enctype="multipart/form-data"> <table width="100%" border=1>
<tr> <td>商品图片</td> <td> <c:if test="${item.pic!=null}"> <img src="/pic/${item.pic}" width=100 height=100/> <br/> </c:if> <input type="file" name="pictureFile"/> </td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="提交" /> </td> </tr>
</table> </form>
spring MVC是支持Json格式的,须要配置@RequestBody
@RequestBody注解用于读取http请求的内容(字符串),经过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
需求:利用ajax传送json数据,contoller类定义方法进行接受,并进行相应
<!-- 注解驱动:可以自动配置最新版的处理器映射器和处理器适配器 --> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
这里当触发input按钮,就会调用ajax请求
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script> <script type="text/javascript"> function sendJson(){ $.ajax({ type:"post", url:"${pageContext.request.contextPath }/sendJson.action",
<!--ajax默认以text文本形式传递,若是要传递json的指定为json--> contentType:"application/json;charset=utf-8", data:'{"name":"测试商品","price":99.9}', success:function(data){ alert(data); } }); } </script> <input type="button" value="sendJson" onClick="sendJson()"/>
//导入jackson的jar包在controller的方法中可使用@RequestBody, //让springMvc将json格式字符串自动转换我java中pojo //注意:页面json中key要等于java中pojo的属性名称 //controller方法返回pojo类型的对象而且用@ResponseBody注解,springMvc会自动将pojo对象转换为json格式字符串 @RequestMapping("/sendJson") @ResponseBody public Items sendJson(@RequestBody Items items) throws Exception{ //public void sendJson(@RequestBody Items items) throws Exception{ System.out.println(items.getName()+"\t"+items.getPrice()); //方式一,返回值为void这里无须设置跳转页面,ajax会自动跳转 //方式二:返回值为Items pojo类,方法中参数必须配置@ResponseBody注解,会给界面返回Item 对象 return items; }
一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件能够更简洁,更有层次,更易于实现缓存等机制。
------ 360百科
简而言之:Restful就是一个资源定位及资源操做的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
资源定位:互联网全部的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
资源操做:使用put、delete、post、get,使用不一样方法对资源进行操做。分别对应添加、删除、修改、查询。通常使用时仍是post和get。Put和Delete几乎不用。
需求:更改访问路径格式,采用Restful风格
1) 配置restful配置
此时须要更改web.xml文件中的拦截对象,之前是针对全部的action("*.action"),如今是针对全部对象("/")
<!-- 开启SpringMVc拦截器--> <servlet> <servlet-name>SpringMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置SpringMvc核心配置文件所在路径 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringMvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMvc</servlet-name> <!-- *.action:表明拦截后缀名为.action结尾的 / :拦截全部可是不包括.jsp /* :拦截全部包括.jsp --> <url-pattern>/</url-pattern> </servlet-mapping>
2) jsp请求书写规范
这里是传递了一个id参数,请求域名中去掉了aciton或者特殊符号
<a href="${pageContext.request.contextPath }/restful/${item.id}">修改</a>
3) 接受参数
经过@RequestMapping("/restful/{id}")接收具备restful风格的域名;@PathVariable 接受参数值
//经过@PathVariable能够接收url中所传过来的参数 //@RequestMapping("/restful/{id}/{张三}")传多参 //@RequestMapping("/restful/{id}")中接受参数使用大括号中加上变量名称,@PathVariable中变量名称要和@RequestMapping中变量名称保持一致 @RequestMapping("/restful/{id}") public String restful(@PathVariable("id") Integer id,HttpServletRequest request,Model model) throws Exception{ // public String restful(@PathVariable("id") Integer id,@PathVariable("张三") String name,HttpServletRequest request,Model model) throws Exception{ Items items=itemsService.findItemsById(id); model.addAttribute("item",items); return "editItem"; }
1) 建立一个自定义拦截器类,继承HandlerInterceptor接口
package cn.clj.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class Interceptor1 implements HandlerInterceptor{ //执行实际:Controller以及执行,ModelAndView已经返回 //使用场景:记录操做日志(如记录用户登陆的ip,时间等) @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("afterCompletion"); } //执行实际:Controller方法已经执行,ModelAndView还没返回 //使用场景:能够再次方法中设置全局的数据处理业务,这里有个ModelAndView,能够添加全局参数 @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub System.out.println("postHandle"); } //返回boolean值:若是返回true:放行;false:拦截 //执行时机:controller方法没有被执行,ModelAndView没有被返回 //使用场景:权限验证 @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { // TODO Auto-generated method stub System.out.println("preHandle"); return true; } }
2) 在springMvc.xml配置拦截器(这里是配置全局拦截器)
<!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!--拦截请求的路径要拦截全部必须配置成/**(不能是/*,它只拦截一层目录) --> <mvc:mapping path="/**"/> 指定拦截器的位置 <bean class="cn.clj.interceptor.Interceptor1"/> </mvc:interceptor> </mvc:interceptors>
3)启动tomcat,就会自动调用拦截器
分析:在登陆界面中,当用户输入本身信息时,会调用后端方法,拦截器检查session中否存在这个用户,核对数据库是否有这个用户,而后进行处理放心仍是拦截
1) 定义一个登陆的拦截器
package cn.clj.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoginInterceptor implements HandlerInterceptor{ @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { // TODO Auto-generated method stub } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { //判断当前访问路径是否为登陆的路径,若是是则放行 if(request.getRequestURI().indexOf("/login")>0){ return true; } //判断session中是否有登陆信息,若是没有则跳转到登陆界面,若是有则放行 HttpSession session=request.getSession(); if(session.getAttribute("username")!=null){ return true; } request.getRequestDispatcher("/jsp/login.jsp").forward(request, response); //其余则拦截 return false; } }
2) 定义一个jsp登陆界面
<form action="${pageContext.request.contextPath}/login/submit" method="post"> <table> <tr> <td>用户名:<input type="text" name="username"/></td></br> <td>密 码:<input type="text" name="password"/></td></br> <td><input type="submit" value="登陆"/></td> </tr> </table> </form>
3) 定义处理登陆的controller类
package cn.clj.controller; import java.io.File; import java.util.Date; import java.util.List; import java.util.UUID; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import cn.clj.pojo.Items; import cn.clj.service.ItemsService; import cn.clj.vo.QueryVo; @Controller @RequestMapping("/login") public class LoginController { //跳转到登陆页面 @RequestMapping("/login") public String login() throws Exception{ return "login"; } @RequestMapping("/submit") public String submit(String username,String password,HttpServletRequest request) throws Exception{ HttpSession session=request.getSession(); //判断用户名密码正确性,若是正确则将登陆信息放入session中 //这里简写,真正项目中要去数据库中校验用户名和密码 if(username!=null){ session.setAttribute("username", username); } //跳转到列表页(注意:这里加了斜杠是用了绝对路径,由于 //二者不属于同一个controller,若是跳转的conrtoller //类前加了窄化请求映射,路径名得为redirect:/items/list) return "redirect:/list"; } }