目录
1 第三天:Spring+SpringMVC 2
1.1 Bean对象的多实例 2
1.1.1 概述 2
1.1.2 为什么用单例或者多例?何时用? 2
1.1.3 applicationContext.xml 4
1.1.4 TestIoC.java 5
1.2 DI依赖注入 5
1.2.1 概述 5
1.2.2 属性的两种注入方式 5
1.3 Set方式注入 6
1.3.1 普通属性 6
1.3.2 对象属性 8
1.4 构造方法注入 11
1.4.1 Dept.java 11
1.4.2 applicationContext.xml 12
1.4.3 TestConstructor.java 14
1.5 ===springmvc 15
1.6 Servlet回顾 15
1.6.1 创建HomeServlet 15
1.6.2 配置web.xml 16
1.6.3 创建home.jsp 16
1.7 Servlet的缺点 16
1.8 设计模式 17
1.8.1 什么是设计模式 17
1.8.2 MVC设计模式 17
1.9 初识springmvc 18
1.9.1 概述 18
1.9.2 表现层的三大课题 18
1.9.3 工作原理 19
1.9.4 性能超群 19
1.10 入门案例 - 注解开发 19
1.10.1 需求 20
1.10.2 创建项目 20
1.10.3 pom.xml 21
1.10.4 tomcat插件 22
1.10.5 HomeController.java 22
1.10.6 home.jsp 23
1.10.7 springmvc-config.xml 23
1.10.8 web.xml 24
1.10.9 启动Tomcat 25
1.10.10 测试 26
1.11 注解 26
1.11.1 什么是注解 26
1.11.2 什么时候用? 26
1.11.3 XML配置方式和注解方式差异 27
1.12 请求 27
1.12.1 常见对象 27
1.12.2 基本数据类型(少量传值) 27
1.12.3 单个POJO对象 28
1.13 拓展 29
1.13.1 springmvc和struts2比较 29
1.13.2 常用的注解 30
1.13.3 @RequestParam 页面名称和action形参名称不一致 30
1.13.4 拦截器 31
第三天:Spring+SpringMVC
Bean对象的多实例
概述
在Spring容器中管理的Bean对象,的作用域可以通过scope属性或用相关注解指定其作用域,最常用是singleton,prototype。其含义如下:
- singleton:单例,是默认值。这个作用域标识的对象具备全局唯一性。
singleton负责对象的创建、初始化、销毁。
- prototype:多例。这个作用域标识的对象每次获取都会创建新的对象。
为什么用单例或者多例?何时用?
之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;
之所以用多例,是为了防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理;
当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;
对于struts2来说,action必须用多例,因为action本身含有请求参数的值,即可改变的状态。
applicationContext.xml
<?xml version=“1.0” encoding=“UTF-8”?>
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd“>
<?xml version=“1.0” encoding=“UTF-8”?>
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd“>
<!-- 声明bean对象,<br /> id:唯一标志<br /> class:bean对象的全路径<br /> --><br /> <!--单例的bean对象<br /> <bean id="hi"<br /> class="cn.tedu.spring.Hello"<br /> scope="singleton"></bean> --><br /> <!-- 多例的bean对象 --><br /> <bean id=_"hi"_ <br /> class=_"cn.tedu.spring.Hello"_<br /> **scope=**_**"prototype"**_></bean><br /> <br /></beans>
TestIoC.java
package cn.tedu.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.tedu.spring.Hello;
public class TestIoc {
//测试spring管理bean对象<br /> @Test<br /> public void ioc(){<br /> //加载核心配置文件<br /> ClassPathXmlApplicationContext ac=<br /> new ClassPathXmlApplicationContext(<br /> "applicationContext.xml");<br /> <br /> //获取bean对象<br /> //hi是在配置文件中bean对象的id值<br /> Hello h = (Hello) ac.getBean("hi");<br /> Hello h2 = (Hello) ac.getBean("hi");<br /> <br /> //==判断两个对象的地址值<br /> //单例返回true,多例返回false<br /> System.out.println(h==h2);<br /> <br /> //调用bean对象的方法<br /> h.hi();<br /> }<br /> <br />}
DI依赖注入
概述
DI(Dependency Injection)依赖注入 。
相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
属性的两种注入方式
对象由spring创建,那么spring是怎么给属性赋值的?spring提供两种方式设置属性值:
Set方式注入
构造方法注入(spring源码大都使用这种方式)
Set方式注入
普通属性
User.java
package cn.tedu.spring;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return “User [name=” + name + “, age=” + age + “]”;
}
}
applicationContext.xml
<?xml version=“1.0” encoding=“UTF-8”?>
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd“>
<!-- 声明bean对象,<br /> id:唯一标志<br /> class:bean对象的全路径<br /> --><br /> <!--单例的bean对象<br /> <bean id="hi" <br /> class="cn.tedu.spring.Hello"<br /> scope="singleton"></bean> --><br /> <!-- 多例的bean对象 --><br /> <bean id=_"hi"_<br /> class=_"cn.tedu.spring.Hello"_<br /> scope=_"prototype"_></bean><br /> <br /> <br /> <br /> <!-- 测试对象的DI依赖注入 <br /> id是唯一标志<br /> class是对象的全路径<br /> --><br /><bean id=_"user"_ class=_"cn.tedu.spring.User"_><br /> <!-- 完成di属性的set方法注入值 <br /> name写的是对象的**属性名**,<br /> value写的是对象**属性的值**<br /> --> <br /> <property name=_"name"_ value=_"tony"_></property><br /> <property name=_"age"_ value=_"20"_></property><br /> <br /></bean><br /> <br /> <br /> <br /></beans>
TestDI.java
package cn.tedu.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.tedu.spring.User;
//测试DI依赖注入
public class TestDI {
@Test<br /> **public** **void** di(){<br /> //加载核心配置文件<br /> ClassPathXmlApplicationContext ac =<br /> **new** ClassPathXmlApplicationContext(<br /> "applicationContext.xml");<br /> <br /> //获取bean对象<br /> User user = (User) ac.getBean("user");<br /> <br /> System._**out**_.println(user);<br /> <br /> }<br /> <br />}
对象属性
可以完成关联对象的赋值动作,比如可以直接注入DAO,注入Service,这就解决了关联对象的注入。这个方式解决了对象直接的关联问题,从而奠基了spring的地位。
User.java
package cn.tedu.spring;
public class User {
**private** String name;<br /> **private** Integer age;<br /> <br /> //加一个关联对象UserInfo<br /> //绑定了两个对象一对一的关系<br /> **private** UserInfo info;<br /> <br /> //getters and setters<br /> <br /> **public** UserInfo getInfo() {<br /> **return** info;<br /> }<br /> **public** **void** setInfo(UserInfo info) {<br /> **this**.info = info;<br /> }<br /> **public** String getName() {<br /> **return** name;<br /> }<br /> **public** **void** setName(String name) {<br /> **this**.name = name;<br /> }<br /> **public** Integer getAge() {<br /> **return** age;<br /> }<br /> **public** **void** setAge(Integer age) {<br /> **this**.age = age;<br /> }<br /> <br /> @Override<br /> **public** String toString() {<br /> **return** "User [name=" + name + ", age=" + age + ", info=" + info + "]";<br /> }<br /> <br /> <br />}
UserInfo.java
package cn.tedu.spring;
public class UserInfo {
//TODO加一个普通属性 tall
//TODO加一个对象属性UserExtra
}
applicationContext.xml
注意:值使用value属性,对象使用ref属性。ref和value不能同时存在
<?xml version=“1.0” encoding=“UTF-8”?>
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd“>
<!-- 声明bean对象,<br /> id:唯一标志<br /> class:bean对象的全路径<br /> --><br /> <!--单例的bean对象<br /> <bean id="hi" <br /> class="cn.tedu.spring.Hello"<br /> scope="singleton"></bean> --><br /> <!-- 多例的bean对象 --><br /> <bean id=_"hi"_<br /> class=_"cn.tedu.spring.Hello"_<br /> scope=_"prototype"_></bean><br /> <br /> <br /> <br /> <!-- 测试对象的DI依赖注入 <br /> id是唯一标志<br /> class是对象的全路径<br /> --><br /><bean id=_"user"_ class=_"cn.tedu.spring.User"_><br /> <!-- 完成di属性的set方法注入值 <br /> name写的是对象的属性名,<br /> value写的是对象属性的值<br /> --> <br /> <property name=_"name"_ value=_"tony"_></property><br /> <property name=_"age"_ value=_"20"_></property><br /> <br /> <!-- di设置对象属性的值 <br /> ref 指定关联对象的id值<br /> --><br /> <property name=_"info"_ **ref**=_"userinfo"_></property> <br /></bean>
<bean id=_"userinfo"_ class=_"cn.tedu.spring.UserInfo"_><br /> </bean><br /> <br /> <br /></beans>
TestDI.java
package cn.tedu.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.tedu.spring.User;
//测试DI依赖注入
public class TestDI {
@Test<br /> **public** **void** di(){<br /> //加载核心配置文件<br /> ClassPathXmlApplicationContext ac =<br /> **new** ClassPathXmlApplicationContext(<br /> "applicationContext.xml");<br /> <br /> //获取bean对象<br /> User user = (User) ac.getBean("user");<br /> <br /> //可以把关联对象的信息也都输出就成功了<br /> System._**out**_.println(user);<br /> <br /> }<br /> <br />}
构造方法注入
Dept.java
package cn.tedu.spring;
//测试构造方法给属性赋值
public class Dept {
private Integer id;<br /> private String name;
//构造方法赋值new Dept(1,"lisi");<br /> public Dept(Integer id,<br /> String name){<br /> this.id=id;<br /> this.name=name;<br /> }
<br /> //getters and setters<br /> public Integer getId() {<br /> return id;<br /> }<br /> public void setId(Integer id) {<br /> this.id = id;<br /> }<br /> public String getName() {<br /> return name;<br /> }<br /> public void setName(String name) {<br /> this.name = name;<br /> }<br /> <br /> <br /> <br /> //toString<br /> @Override<br /> public String toString() {<br /> return "Dept [id=" + id + ", name=" + name + "]";<br /> }<br /> <br />}
applicationContext.xml
<?xml version=”1.0” encoding=”UTF-8”?>
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- 声明bean对象,<br /> id:唯一标志<br /> class:bean对象的全路径<br /> --><br /> <!--单例的bean对象<br /> <bean id="hi"<br /> class="cn.tedu.spring.Hello"<br /> scope="singleton"></bean> --><br /> <!-- 多例的bean对象 --><br /> <bean id="hi"<br /> class="cn.tedu.spring.Hello"<br /> scope="prototype"></bean><br /> <br /> <br /> <br /> <!-- 测试对象的DI依赖注入<br /> id是唯一标志<br /> class是对象的全路径<br /> --><br /><bean id="user" class="cn.tedu.spring.User"><br /> <!-- 完成di属性的set方法注入值<br /> name写的是对象的属性名,<br /> value写的是对象属性的值<br /> --><br /> <property name="name" value="tony"></property><br /> <property name="age" value="20"></property><br /> <br /> <!-- di设置对象属性的值<br /> ref 指定关联对象的id值<br /> --><br /> <property name="info" ref="userinfo"></property><br /></bean>
<bean id="userinfo" class="cn.tedu.spring.UserInfo"><br /> </bean><br /> <br /> <br /> <!-- 测试构造方法赋值 --><br /> <bean id="dept" class="cn.tedu.spring.Dept"><br /> <br /> **<!-- 当构造函数中有多个参数时,**<br />** 需要index属性绑定参数的位置**<br />** 注意:index属性的值从0开始**<br />** -->**<br /> <constructor-arg index="0" value="10"></constructor-arg><br /> <constructor-arg index="1" value="研发部"></constructor-arg><br /> </bean><br /> <br /> <br /></beans>
TestConstructor.java
@Test<br /> public void di2(){<br /> //加载核心配置文件<br /> ClassPathXmlApplicationContext ac =<br /> new ClassPathXmlApplicationContext(<br /> "applicationContext.xml");<br /> <br /> //获取bean对象<br /> Dept d = (Dept) ac.getBean("dept");<br /> //可以把关联对象的信息也都输出就成功了<br /> System.out.println(d);<br /> <br /> }<br />
===springmvc
Servlet回顾
创建HomeServlet
package cn.tedu.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HomeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {<br /> <br />String age = **request.getParameter("age");**<br /> int i = Integer.valueOf(age);<br /> System.out.println(i);<br /> <br /> String birth = request.getParameter("birthday");<br /> System.out.println(birth);<br /> SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");<br /> try {<br /> Date date = sdf.parse(birth);<br /> System.out.println(date.getMonth());<br /> } catch (ParseException e) {<br /> e.printStackTrace();<br /> }
//跳转jsp页面
request.getRequestDispatcher(
“/WEB-INF/pages/home.jsp”).forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {<br /> doGet(request, response);<br /> }
配置web.xml
<?xml version=“1.0” encoding=“UTF-8”?>
xmlns:web=“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_ID” version=“3.0”>
创建home.jsp
/WEB-INF/pages/home.jsp
<%@ page language=”java” contentType=”text/html; charset=utf-8”
pageEncoding=”utf-8”%>
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd">
i’m home page~
Servlet的缺点
每个Servlet声明时需要在web.xml中配置8行代码,配置繁琐,内容多,web.xml结构不清晰,不易维护。团队开发冲突不断。
一般来说,每个Servlet只处理一个请求,如果要实现数据库表的CRUD操作,需要写4个Servlet。
获取参数繁琐只能强制转类型,复杂的还需特殊处理。如日期类型转换,代码繁多重复手工劳动,非业务代码。
设计模式
什么是设计模式
设计模式就是一种模子,经过多年实践锤炼形成一套行之有效的完成某个特定任务的步骤和方式。例如:西凤酒的酿造过程,酿造工序,前后不能变,温差不能变,这样做就是好喝,稍微改动就变味道了。再如,北京烤鸭,就是那样做,就是那些调料腌制,变量配比,味道口感就是不如人家。
MVC设计模式
用来进行分层的结构,这样代码分离结构清晰,各层代码,各司其职,易于开发大型项目。
MVC(Model模型、View视图、Control控制层),将软件进行分层达到松耦合的效果。
通用的软件编程思想, 在MVC设计模式中认为, 任何软件都可以分三层:控制层(Controller)、数据处理模型(Model)、负责展示数据的视图(View)。
在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面这三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分。如果某一个模块发生变化,应该尽量做到不影响其他两个模块。提高代码的可读性,实现程序间的松耦合、提高代码复用性。
初识springmvc
概述
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一 般不用),Struts2(一般老项目使用)等。
SpringMVC就是基于MVC设计模式来实现的。
我们的POJO/domain就是Model层,我们的JSP就是视图层,我们的Controller就是控制层。
现在主流基于SSM三大框架开发都是在MVC上继续演化,又分为持久层DAO,业务层Servie,控制层Controller。持久层用来和数据库读写ORM,业务层用来处理复杂的业务逻辑,控制层用来处理MVC的控制。
表现层的三大课题
URL到框架的映射
http请求参数绑定
http响应的生成和输出
工作原理
性能超群
入门案例 - 注解开发
从springmvc2.5开始引入注解方式,特别到了3.0就全面引入注解方式,号称xml零配置。spring3.0配置注解引入后也就是这个点成为了它和struts2的分水岭。随着springmvc的成熟,struts2开始落幕,趋于被市场淘汰。
需求
访问链接: http://localhost:8060/home
转向页面: /WEB-INF/pages/home.jsp
创建项目


pom.xml
<dependencies><br /> <!-- 单元测试 --><br /> <dependency><br /> <groupId>junit</groupId><br /> <artifactId>junit</artifactId><br /> <version>${junit.version}</version><br /> <scope>test</scope><br /> </dependency>
<!-- SpringMVC --><br /> <dependency><br /> <groupId>org.springframework</groupId><br /> <artifactId>spring-webmvc</artifactId><br /> <version>${spring.version}</version><br /> </dependency><br /> <br /> <!-- Servlet支持Request和Response --><br /> <dependency><br /> <groupId>javax.servlet</groupId><br /> <artifactId>servlet-api</artifactId><br /> <version>2.4</version><br /> <scope>provided</scope><br /> </dependency><br /> <br /> <!-- java对象转换json的工具类 --><br /> <dependency><br /> <groupId>com.fasterxml.jackson.core</groupId><br /> <artifactId>jackson-databind</artifactId><br /> <version>2.5.1</version><br /> </dependency><br /> </dependencies><br /></project>
tomcat插件
<build><br /> <plugins><br /> <plugin><br /> <groupId>org.apache.tomcat.maven</groupId><br /> <artifactId>tomcat7-maven-plugin</artifactId><br /> <version>2.2</version><br /> <configuration><br /> <port>8060</port><br /> <path>/</path><br /> </configuration><br /> </plugin><br /> </plugins><br /> </build>
HomeController.java
package cn.tedu.controller;
//测试springmvc框架
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//@Controller表示这个类是springmvc的控制层代码
@Controller
public class HomeController {
//映射请求和方法的关系<br /> @RequestMapping("hello")<br /> public String hello(){<br /> //home是要跳转的页面<br /> return "home";<br /> }<br /> <br /> <br />}
home.jsp
/WEB-INF/pages/home.jsp
<%@ page language=”java” contentType=”text/html; charset=utf-8”
pageEncoding=”utf-8”%>
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd">
i’m home page~
springmvc-config.xml
<?xml version=”1.0” encoding=”UTF-8”?>
xmlns:mvc=”http://www.springframework.org/schema/mvc“
xmlns:context=”http://www.springframework.org/schema/context“
xsi:schemaLocation=”http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
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">
<!-- 1、配置注解驱动:识别注解标志 --><br /> <mvc:annotation-driven></mvc:annotation-driven><br /> <br /> <!-- 2、配置包扫描 <br /> base-package:基于哪个包进行扫描<br /> --><br /> <context:component-scan <br /> base-package="cn.tedu.controller"></context:component-scan>
<!-- 3、内部资源视图解析器 <br /> 最终实现把页面的正确路径进行拼接<br /> /WEB-INF/pages/ home .jsp<br /> --><br /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><br /> <property name="prefix" value="/WEB-INF/pages/"></property><br /> <property name="suffix" value=".jsp"></property><br /> </bean><br /> <br /> <br /></beans>
web.xml
<?xml version=”1.0” encoding=”UTF-8”?>
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd“
id=”WebApp_ID” version=”3.0”>
<!-- 整合springmvc --><br /> <servlet><br /> <servlet-name>springmvc</servlet-name><br /> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><br /> <br /> <!-- 指定springmvc的核心配置文件的位置 --><br /> <init-param><br /> <param-name>contextConfigLocation</param-name><br /> <param-value>classpath:springmvc-config.xml</param-value><br /> </init-param><br /> <br /> </servlet><br /> <servlet-mapping><br /> <servlet-name>springmvc</servlet-name><br /> <br /> <!-- 拦截所有请求 --><br /> <url-pattern>/</url-pattern><br /> </servlet-mapping>
启动Tomcat



测试
注解
什么是注解
@ 是java注解,即annotation。
可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用
要先学习java的反射机制,然后再来理解java注解
什么时候用?
我们一般用不到自定义注解,框架为我们提供了很多注解,只要在代码里写明你需要的注解就可以了。只有在自己动手写类似于Hibernate框架的时候,会用到自定义注解。这也是为什么我们一般用不到java反射,因为只有在使用自定义注解的时候,才会用到java反射,而我们平时连自定义注解都用不到。
XML配置方式和注解方式差异
Controller无需在xml中声明,加个@Controller注解即可,这样再多的Controller也不怕了。只需xml中配置一次注解驱动
原来要在xml配置bean来指明映射关系,现在只加注解@RequestMapping无需xml配置
无需返回ModelAndView对象,直接返回逻辑名即可
参数自动封装,自动类型转换
一句话太简洁方便了!所以现在springmvc已经成为业界主流前台开发框架。
请求
常见对象
springmvc参数非常灵活,你要你说,直接在方法的参数中声明即可
HttpServletRequest
HttpServletResponse
HttpSession
基本数据类型(少量传值)
自动转换类型,parameter中只有字符串。
形参名称必须和页面中定义的控件名称相同。
在方法的括号里直接写所要的参数,并且声明它对应的类型。
单值
日期
日期类型2017/06/08就正确,怎么2017-06-08就出错了呢?400错误,参数类型不匹配错误。springmvc默认日期格式用**斜杠隔开。
使用@InitBinder注解,指定自定义的日期转换格式**
@InitBinder //日期转换设定
public void InitBinder (ServletRequestDataBinder binder){
binder.registerCustomEditor(
java.util.Date.class,
new CustomDateEditor(new SimpleDateFormat(“yyyy-MM-dd”), true));
}
测试:
http://localhost:8060/add?id=10&name=tony&birthday=2018-10-11
单个POJO对象
创建UserController
创建User
package cn.tedu.pojo;
import java.util.Date;
public class User {
**private** **int** id;<br /> **private** String name;<br /> **private** **int** age;<br /> **private** Date birth;<br /> <br /> **public** **int** getId() {<br /> **return** id;<br /> }<br /> <br /> **public** **void** setId(**int** id) {<br /> **this**.id = id;<br /> }<br /> **public** String getName() {<br /> **return** name;<br /> }<br /> **public** **void** setName(String name) {<br /> **this**.name = name;<br /> }<br /> **public** **int** getAge() {<br /> **return** age;<br /> }<br /> **public** **void** setAge(**int** age) {<br /> **this**.age = age;<br /> }<br /> **public** Date getBirth() {<br /> **return** birth;<br /> }<br /> **public** **void** setBirth(Date birth) {<br /> **this**.birth = birth;<br /> }<br /> <br /> @Override<br /> **public** String toString() {<br /> **return** "User [id=" + id + ", name=" + name + ", age=" + age + ", birth=" + birth + "]";<br /> }<br /> <br />}
测试
拓展
springmvc和struts2比较
| 技术 | 核心分发器 | 拦截级别 | 说明 |
|---|---|---|---|
| Struts1 | DispatcherServlet | 类级别 | 基于Servlet实现 企业中很多旧项目采用的框架 action是单例模式,线程不安全的。 Struts1使用JSTL EL表达式,但是对集合和索引属性的支持很弱。 |
| Struts2 | DispatcherFilter | 类级别 一个类对应一个request上下文 |
基于Filter实现 Struts2 action是原型模式 prototype,每次访问对象都会创建新的实例,保证线程安全性; 采用 OGNL解析页面标签。 Struts2是基于松耦合,和web容器脱钩ValueStack 复杂值栈、多例、OGNL导致性能低 安全漏洞频繁,不安全 |
| SpringMVC | DispatcherServlet | 方法级别 一个方法对应一个request上下文,而方法同时又跟一个url对应。 |
基于Servlet实现 Springmvc controller是单例模式,整个程序只有一个对象实例。Spring的安全性是通过绑定threadlocal实现 Spring3 mvc可以认为已经99.9%零配置了。 采用JSTL解析页面标签 基于web容器、单例、JSTL导致性能高 |
常用的注解
@Controller 标识是一个Controller,Spring包扫描创建实例
@RequestMapping 请求后的映射路径
@PathVariable 标识接收单个参数
@RespringBody 返回对象利用jackson工具类转换为json字符串
@RequestParam 参数名和请求参数名称不同时使用,可以设置默认值
@RequestParam 页面名称和action形参名称不一致
| value | 参数名字,即入参的请求参数名字,如value=“delId”表示请求的参数区中的名字为delId的参数的值将传入 |
|---|---|
| required | 是否必须,默认是true,表示请求中一定要有相应的参数,否则将报400错误码; |
| defaultValue | 默认值,表示如果请求中没有同名参数时的默认值 |
@RequestMapping(“add”)
public String add(User user,@RequestParam**(value=“username”)String **name){
System.out.println(user);
System.out.println(name);//lisi
return “home”;
}
http://localhost:8060/user/add?id=1**&username=lisi**&age=20&birth=2009-4-9
拦截器
SpringMVC框架自动将配置的拦截器注入到所有的mapping中
拦截器实现性能监控
TimeInterceptor
package cn.tedu.springmvc.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class TimeInterceptor implements HandlerInterceptor{
//ThreadLocal解决线程安全问题
private ThreadLocal
@Override //执行handle前执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Long startTime = System.currentTimeMillis();
tStartTime.set(startTime);
return true;
}
@Override //处理handle后执行<br /> public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,<br /> ModelAndView modelAndView) throws Exception {<br /> try{<br /> Long stopTime = System.currentTimeMillis();<br /> Long executeTime = stopTime - tStartTime.get();<br /> System.out.println("执行时间:"+executeTime+" 毫秒");<br /> }finally{<br /> tStartTime.remove(); //不释放会引起内存泄漏<br /> }<br /> }
@Override //处理handle完毕后,返回ModelAndView对象前执行<br /> public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)<br /> throws Exception {<br /> <br /> }
拦截配置
<!-- 拦截器 --><br /> <mvc:interceptors><br /> <mvc:interceptor><br /> <mvc:mapping path="/**"/><br /> <bean class="cn.tedu.springmvc.controller.TimeInterceptor"/><br /> </mvc:interceptor><br /> </mvc:interceptors>
