1.MVC模型
2.SpringMVC概述
2.1SpringMVC是什么
2.2SpringMVC在三层架构的位置
2.3SpringMVC的优势
2.4SpringMVC和Struts2的优略分析
3.SpringMVC的入门程序
3.1需求
3.2创建WEB工程,引入开发的jar包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.itcast</groupId> <artifactId>springmvc_day01_01start</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>springmvc_day01_01start Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target>
<!--版本锁定:dependency里面的配置可以都用这个版本,方便后续修改版本和维护-->
<spring.version>5.0.2.RELEASE</spring.version>
</properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>springmvc_day01_01start</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
3.3 配置核心的控制器(配置DispatcherServlet)
在web.xml配置文件中核心控制器DispatcherServlet
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--配置前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <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>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
部署
3.4编写springmvc.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="cn.itcast"/> <!-- 视图解析器对象 --> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 开启SpringMVC框架注解的支持 --> <mvc:annotation-driven /> </beans>
3.5编写index.jsp和HelloController控制器类
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>入门程序</h3> <a href="hello">入门程序</a> </body> </html>
package cn.itcast.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; //控制器类 @Controller public class HelloController { @RequestMapping(path="/hello") public String sayHello(){ System.out.println("hello springMVC"); return "success"; } }
3.6在WEB-INF目录下创建pages文件夹,编写success.jsp的成功页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>入门成功了</h3> </body> </html>
4.入门案例中涉及的组件
4.1DispatcherServlet:前端控制器
4.2HandlerMapping:处理器映射器
4.3Handler
4.4HandlAdapter:处理器适配器
4.5View Resolver:视图解析器
4.6View:视图
4.7<mvc:annotation-driven> 说明
5.RequestMapping 注解
5.1出现位置
1.方法上
2.类上
跳转路径必须是user/*,否则报错。
5.2属性
6.请求参数的绑定
6.1请求参数的机制
1. 表单提交的数据都是k=v格式的 username=haha&password=123
2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
3. 要求:提交表单的name和参数的名称是相同的
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--请求参数绑定--%> <a href="param/testParam?username=hehe&password=123">请求参数绑定</a> </body> </html>
package cn.itcast.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 请求参数绑定的入门 * * @return */ @RequestMapping("/testParam") public String testParam(String username, String password) { System.out.println("执行了..."); System.out.println("username:" + username); System.out.println("password:" + password); return "success"; } }
6.2 支持的数据类型
实体类型
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--把数据封装Account类中--%> <form action="param/saveAccount" method="post"> 姓名:<input type="text" name="username" /><br/> 密码:<input type="text" name="password" /><br/> 金额:<input type="text" name="money" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
package cn.itcast.controller; import cn.itcast.domain.Account; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 请求参数绑定把数据封装到javaBean的类中 * * @return */ @RequestMapping("/saveAccount") public String saveAccount(Account account) { System.out.println("执行了..."); System.out.println(account); return "success"; } }
实体类中包含引用类型
package cn.itcast.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private String uname; private Integer age; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "uname='" + uname + '\'' + ", age=" + age + '}'; } }
package cn.itcast.domain; import java.io.Serializable; public class Account implements Serializable{ private String username; private String password; private Double money; private User user; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", money=" + money + ", user=" + user + '}'; } }
package cn.itcast.controller; import cn.itcast.domain.Account; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 请求参数绑定把数据封装到javaBean的类中 * * @return */ @RequestMapping("/saveAccount") public String saveAccount(Account account) { System.out.println("执行了..."); System.out.println(account); return "success"; } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--把数据封装Account类中--%> <form action="param/saveAccount" method="post"> 姓名:<input type="text" name="username" /><br/> 密码:<input type="text" name="password" /><br/> 金额:<input type="text" name="money" /><br/> 用户姓名:<input type="text" name="user.uname" /><br/> 用户年龄:<input type="text" name="user.age" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
请求参数中文乱码的解决
在web.xml中添加一个过滤器
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--配置前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <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>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--配置解决中文乱码的过滤器--> <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> </web-app>
实体类中包含集合数据类型
package cn.itcast.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private String uname; private Integer age; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "uname='" + uname + '\'' + ", age=" + age + '}'; } }
package cn.itcast.domain; import java.io.Serializable; import java.util.List; import java.util.Map; public class Account implements Serializable { private String username; private String password; private Double money; private List<User> list; private Map<String, User> map; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } public Map<String, User> getMap() { return map; } public void setMap(Map<String, User> map) { this.map = map; } @Override public String toString() { return "Account{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", money=" + money + ", list=" + list + ", map=" + map + '}'; } }
package cn.itcast.controller; import cn.itcast.domain.Account; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 请求参数绑定把数据封装到javaBean的类中 * * @return */ @RequestMapping("/saveAccount") public String saveAccount(Account account) { System.out.println("执行了..."); System.out.println(account); return "success"; } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--把数据封装Account类中,类中存在list和map集合--%> <form action="param/saveAccount" method="post"> 姓名:<input type="text" name="username" /><br/> 密码:<input type="text" name="password" /><br/> 金额:<input type="text" name="money" /><br/> 用户姓名:<input type="text" name="list[0].uname" /><br/> 用户年龄:<input type="text" name="list[0].age" /><br/> 用户姓名:<input type="text" name="map['one'].uname" /><br/> 用户年龄:<input type="text" name="map['one'].age" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
7.自定义类型转换器
7.1使用场景
package cn.itcast.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable{ private String uname; private Integer age; private Date date; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @Override public String toString() { return "User{" + "uname='" + uname + '\'' + ", age=" + age + ", date=" + date + '}'; } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--自定义类型转换器--%> <form action="/param/saveUser" method="post"> 用户姓名:<input type="text" name="uname" /><br/> 用户年龄:<input type="text" name="age" /><br/> 用户生日:<input type="text" name="date" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
package cn.itcast.controller; import cn.itcast.domain.Account; import cn.itcast.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 自定义类型转换器 * * @return */ @RequestMapping("/saveUser") public String saveUser(User user) { System.out.println("执行了..."); System.out.println(user); return "success"; } }
但是输入的日期格式如果是这样,则提示错误:
7.2解决方法
1.自定义类型转换器
package cn.itcast.utils; import org.springframework.core.convert.converter.Converter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * 把字符串转换日期 */ public class StringToDateConverter implements Converter<String, Date> { /** * * @param source : 传入进来字符串 * @return */ @Override public Date convert(String source) { // 判断 if(source == null){ throw new RuntimeException("请您传入数据"); } DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { // 把字符串转换日期 return df.parse(source); } catch (Exception e) { throw new RuntimeException("数据类型转换出现错误"); } } }
2.在 springmvc.xml配置文件中配置类型转换器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="cn.itcast"/> <!-- 视图解析器对象 --> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <!--配置自定义类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itcast.utils.StringToDateConverter"/> </set> </property> </bean> <!-- 开启SpringMVC框架注解的支持 --> <mvc:annotation-driven conversion-service="conversionService"/> <!-- 在 annotation-driven 标签中引用配置的类型转换服务--> </beans>
运行成功
8.获取Servlet原生的API
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <a href="/param/testServlet">Servlet原生的API</a> </body> </html>
package cn.itcast.controller; import cn.itcast.domain.Account; import cn.itcast.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * 请求参数绑定 */ @Controller @RequestMapping("/param") public class ParamController { /** * 原生的API * * @return */ @RequestMapping("/testServlet") public String testServlet(HttpServletRequest request, HttpServletResponse response) { System.out.println("执行了..."); System.out.println(request); HttpSession session = request.getSession(); System.out.println(session); ServletContext servletContext = session.getServletContext(); System.out.println(servletContext); System.out.println(response); return "success"; } }