我们在开发时将应用一般划分为三层:即表现层,业务层,持久层。三层结构各司其职,每一层都会实现特定的功能,我们来看看每一层都做了什么事情:
表现层:即我们所说的web层,一般会调用业务层。负责接收客服端的请求,以及发送响应到客户端,web层的设计一般使用MVC模型,也就是说MVC只是web层的设计模式。
业务层:即service层,业务层负责业务逻辑的处理,一般会调用持久层,会涉及到数据的持久化(即数据存取),所以要保证事务的一直性,也就是常说的事务交给业务层来处理。
持久层:即dao层,负责数据的持久化,与数据库交互,完成对表的增删查改。
MVC,即model(模型),view(视图),controller(控制器)。前面说过,它是三层架构中web层的一种设计模式。
model: 通常指数据模型,用来封装数据。
view: 通常指jsp,html。用来展示数据。
controller:用来与客户端交互,一般用来处理逻辑的,例如客户端请求一个jsp页面,就给你跳转到这个页面。
现在来说说springMVC,springMVC它是用java语言实现了MVC设计模型的轻量级web框架,是属于springframework的后续产品。也就是说springMVC框架在三层架构中是处于web层的位置,它可以使我们开发web应用变得非常方便高效。
1、清晰的角色划分:
前端控制器(DispatcherServlet)
请求到处理器映射(HandlerMapping)
处理器适配器(HandlerAdapter)
视图解析器(ViewResolver)
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command 请求参数绑定到的对象就叫命令对象)
表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
3、由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象。
4、和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
5、可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
6、可定制性,HandlerMapping、ViewResolver 等能够非常简单的定制。
7、功能强大的数据验证、格式化、绑定机制。
8、利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
10、强大的 JSP 标签库,使 JSP 编写更容易。
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
置支持等等。
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatchServlet</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>dispatchServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.control"></context:component-scan>
<!-- 配置视图解析器 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置类型转换器 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters" >
<set>
<bean id="" class="cn.itcast.utils.StringtoDateConvertor"></bean>
</set>
</property>
</bean>
<!-- 开启springMVC注解支持 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
</beans>
@Controller(value="/hello")
@RequestMapping(value="/user")
public class HelloController {
/*
* 入门案例
*/
@RequestMapping(value="/hello")
public String test(){
System.out.println("hello");
return "succeed";
}
}
只输出一句话,用于测试
我们在开发中会经常根据请求参数做一些相应的处理,那么我们怎么拿到请求参数呢?springMVC为我们提供了强大的参数绑定机制,通过把请求参数作为控制器中方法参数进行绑定。
支持的数据类型
使用要求:
如果是基本类型或者 String 类型:要求我们的参数名称必须和控制器中方法的形参名称保持一致。(严格区分大小写)
如果是 POJO 类型,或者它的关联对象:要求表单中参数名称和 POJO 类的属性名称保持一致。并且控制器方法的参数类型是 POJO 类型。
如果是集合类型,有两种方式:
第一种:要求集合类型的请求参数必须在 POJO 中。在表单中请求参数名称要和 POJO 中集合属性名称相同。给 List 集合中的元素赋值,使用下标给 Map 集合中的元素赋值,使用键值对。
第二种:
接收的请求参数是 json 格式数据。需要借助一个注解实现
1. 基本类型的参数绑定
jsp代码
<!--在jsp中准备一个链接用于提交请求参数-->
<a href="user/testParam?id=8&name=Kobe">测试基本类型参数绑定</a>
controller代码:
/*
* 基本类型参数绑定
*/
@RequestMapping(value="/testParam")
public String testRequest(Integer id,String name){
System.out.println("id:"+id+"name:"+name);
return "succeed";
}
2. POJO类型作为参数
Account实体类:
public class Account {
private String username;
private String password;
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;
}
@Override
public String toString() {
return "Account [username=" + username + ", password=" + password + "]";
}
}
jsp代码:
jsp代码:
<form action="user/testPOJO" method="post">
姓名:<input type="text" name="name"/><br>
密码:<input type="password" name="password" /><br>
<input type="submit" value="登录"/>
</form>
控制器方法:
/*
* pojo类型参数
*/
@RequestMapping("testPOJO")
public String testPOJO(Account account){
System.out.println(account);
return "succeed";
}
在前面的参数中特意没有使用中文,原因是会出现乱码问题!!springMVC为我们提供了一个过滤器org.springframework.web.filter.CharacterEncodingFilter,我们就不需要自己写过滤器了。只需要在web.xml中配置这个过滤器就行。
<!-- 配置过滤器,用于处理中文乱码 -->
<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>/*
这时候在表单输入中文也不会出现乱码了。
springMVC可以帮我们进行一些基本类型的转换,例如string类型转换成Integer。但是有些特殊情况,类中有个Date类型的属性,而在表单中提交的是String类型,springMVC无法帮我们进行类型转换,这时候我们就需要自定义类型转换器了。
步骤:
package cn.itcast.utils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.core.convert.converter.Converter;
/*
* 自定义日期类型转换器
*/
public class StringtoDateConvertor implements Converter<String, Date>{//string装换Date
public Date convert(String source) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(source);
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("日期转换出错");
}
}
}
<!-- 配置类型转换器,将自定义的类型转换器注册到类型转换器中 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters" >
<set>
<bean id="" class="cn.itcast.utils.StringtoDateConvertor"></bean>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
此时,我们就可以完成把符合格式的String类型转换成Date类型了。
RequestParam注解
作用:把请求中的指定名称的参数传递给控制器中的形参赋值
属性:
value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供
RequestBody注解
作用:用于获取请求体的内容(注意:get方法不可以)
属性
required:是否必须有请求体,默认值是true
PathVariable注解
作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
属性
value:指定url中的占位符名称
RequestHeader注解
作用:获取指定请求头的值
属性
value:请求头的名称
CookieValue注解
作用:用于获取指定cookie的名称的值
属性
value:cookie的名称
代码
ModelAttribute注解
作用
出现在方法上:表示当前方法会在控制器方法执行前线执行。
出现在参数上:获取指定的数据给参数赋值。
应用场景
当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
SessionAttributes注解
作用:用于多次执行控制器方法间的参数共享
属性
value:指定存入属性的名称