三层架构和MVC
1、三层架构
-
使用Java语言基本上都是开发B/S架构的程序,BS架构又分成了三层架构
* 表现层:web层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模式 * 业务层:处理公司具体的业务逻辑的 * 持久层:用来操作数据库的
2、MVC模型
-
MVC-----Model View Controller 模型视图控制器
* model:数据模型,JavaBean的类,用来进行数据封装 * View:指的是JSP,HTML用来展示数据给用户 * Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。
SpringMVC入门案例学习
1、概述
-
MVC概述
* 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级web框架 * SpringMVC属于SpringFrameWork的后续产品,已经融合在SpringWebFlow里面。Spring框架提供了构建Web应用程序的全功能MVC模块 * 使用Spring可插入的MVC架构,从而在使用Spring进行web开发时,可以选择使用Spring的SpringMVC框架杭州集成其他MVC开发框架,比如Struts2
-
SpringMVC在三层架构中的位置
* 表现层
-
SpringMVC的优势
-
SpringMVC与Structs2框架对比
2、SpringMVC的入门程序
3、入门案例的执行过程分析
入门案例的执行流程
SpringMVC官方提供图形
入门案例中的组件分析
-
前端控制器(DispatcherServlet)
用户请求到达前端控制器,它就相当于MVC模式中的C,DispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。
-
处理器映射器(HandlerMapping)
HandlerMapping负责根据用户请求找到Handler即处理器,SpringMVC提供了不同的映射器实现类不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
-
处理器(Handler)
-
处理器适配器(HandlerAdapter)
-
视图解析器(View Resolver)
-
视图(View)
4、RequestMapping注解
1、RequestMapping注解的作用:
> 建立请求URL和处理方法之间的关系
2、RequestMapping注解可以作用在方法和类上
> 作用在类上:第一级的访问目录
> 作用在方法上:第二级访问目录
> 细节: 路径可以不编写 / 表示应用的根目录开始
> 细节: ${pageContext.request.contextPath}也可以省略不写,但是路径上不能些/
3、RequestMapping的属性
> path 指定请求路径的URL
> value value和path属性是一样的
> mthod 指定该方法的请求方式
> params 指定限制请求参数的条件
params = {"username"}:表示请求中必须有username
params={"money!100"}: 表示请求参数中money不能是100
> headers 发送的请求中必须包含的请求头
访问:http://localhost:8080/springmvc_day01_01_start_war/user/hello?username=heihei
表示请求是:http://localhost:8080/springmvc_day01_01_start_war/user/hello?username=heihei&money>100
其他的比如http://localhost:8080/springmvc_day01_01_start_war/user/hello?username=heihei&money>150
http://localhost:8080/springmvc_day01_01_start_war/user/hello?username=heihei&money=150
之类的都不能访问成功
请求参数的绑定
1、绑定说明
绑定机制
表单中请求参数都是基于key=value的。
SpringMVC绑定请求参数的过程是通过把表单提交请求参数,转为控制器的参数进行绑定的。
支持的数据类型
- 基本类型参数:包括基本类型和String类型
- POJO类型参数:包括实体类,以及关联的实体类
- 数组和集合类型参数:包括List结构和Map结构的集合(包括数组)
SpringMVC绑定请求i参数是自动实现的,但是想要使用,必须遵守使用要求
使用要求
- 如果是基本类型或者String类型:
参数名称必须和控制器中方法的形参名称保持一致。(严格区分大小写)
- 如果是POJO类型,或者它的关联对象:
如果表单中参数名称和POJO类的属性名称保持一致。并且控制器方法的参数类型是POJO类型
- 如果是集合类型,有两种方式
要求集合类型的请求参数必须在POJO中。在表单中请求参数名称要和POJO中集合属性名称相同
- 给List集合中的元素赋值,使用下标
- 给Map集合中的元素赋值,使用键值对
接收的请求参数是json格式数据。要借助注解实现
基本类型和String类型作为参数
http://localhost:8080/springmvc_day01_01_start_war/findAccount?accountId=1&accountName=oceanstar
POJO作为参数
- 实体类代码
- 控制类
- jsp代码
POJO中包含集合参数
- 实体类
- 控制类
- jsp代码
注意1:money为float类型,必须写出数字格式,否则有:
常用注解
1、RequestParam
- 作用:
把请求中指定名称的参数给控制器中的形参赋值
- 属性:
- value:指定参数中的名称
- required: 请求参数中是否必须提供此参数, 默认为true
- 实例
访问:http://localhost:8080/springmvc_day01_01_start_war/testAnno?name=ocean
或者:http://localhost:8080/springmvc_day01_01_start_war/testAnno?name=ocean&age=18
结果:
2、RequestBody
- 作用:
- 用于获取请求体内容,直接使用得到的是key=value&key=value。。。结构的数据
- get请求方法不适用
- 属性
- required: 请求参数中是否必须有请求体, 默认为true。当取值为true时,个体请求方式会报错,当值为false时,否则为null
- 实例
访问:
结果:
3、PathVaribale
- 作用:
- 用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是url占位符
- url支持占位符时spring3.0之后加入的,是springMVC支持rest风格url的一个重要标识
- 属性
value:用于指定url中占位符名称
required:是否必须提供占位符
- 实例
访问:
http://localhost:8080/springmvc_day01_01_start_war/testAnno/11
4、RequestHeader
- 作用:
用于获取请求消息头
- 属性:
- value:指定消息头名称
- required: 请求参数中是否必须提供此消息头
- 注意:
实际开发中不怎么用
- 实例
http://localhost:8080/springmvc_day01_01_start_war/testAnno
5、CookieValue
- 作用:
用于把指定cookie名称的值传入控制器方法参数
- 属性
value:用于指定cookie名称
required:是否必须有cookie
- 实例
http://localhost:8080/springmvc_day01_01_start_war/testAnno
6、ModelAttribute
- 作用:
该注解是SpringMVC4.3版本之后新加入的。它可以用于修饰方法和参数
- 修饰方法:表示当前方法会在控制器的方法执行之前先执行。它可以修饰没有返回值的方法,也可以修饰有返回值的方法
- 修饰参数:获取指定的数据给参数赋值
- 属性:
value:用于获取数据的key。key可以是POJO的属性名从,也可以是map的key
- 应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
基于POJO属性的基本使用
访问:http://localhost:8080/springmvc_day01_01_start_war/testAnno
结果:
结论:被ModelAttribute的方法会在控制器的方法执行之前先执行
基于Map的应用场景实例:ModelAttribute修饰方法带返回值
需求:如果年龄不填,那就默认为20岁。如果填写,填写的就是真实年龄
基于Map的应用场景实例:ModelAttribute修饰方法不带返回值
需求:如果年龄不填,那就默认为20岁。如果填写,填写的就是真实年龄
7、sessionAttribute
- 作用:
用于多次执行控制器方法间的参数共享
- 属性;
- value:用于指定存入的属性名称
- type:用于指定存入的数据类型
- 实例
返回值类型及响应数据类型
1、返回字符串
1、最简单的应用:controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。
2、具体应用
- 控制层
- success. jsp
2、返回ModelAndView对象
ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
作用和上面返回spring的一样
3、返回void
1、如果控制器的方法返回值写出void,执行程序报404
2、可以是使用请求转发或者重定向到指定的页面,也可以直接渲染
4、SpringMVC框架提供的转发和重定向
- forward请求转发:
- redirect重定向:
注意:如果重定向到jsp页面,则jsp页面不能写在WEB-INF目录中,否则无法找到
5、ResponseBoday响应json数据[待修改]
- 作用:该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如json等通过response响应给客户端
1、DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源也会被拦截到,从而不能被使用。如果要解决这个问题,可以在springmvc.xml配置文件中添加如下配置
<!--前端控制器,哪些静态资源不拦截-->
<!-- <mvc:resources location="/css/" mapping="/css/**"/>-->
<!-- <mvc:resources location="/images/" mapping="/images/**"/>-->
<!-- <mvc:resources location="/js/" mapping="/js/**"/>-->
mvc:resources:配置标签不过滤
- location:表示webapp目录下报的所有文件
- mapping:表示以/static开头的所有请求路径
2、使用@RequestBody获取请求体数据
3、使用@RequestBody注解将json的字符串转换成javaBean对象
文件上传
1、文件上传的必要前提
- method属性取值必须是post
- form表单的enctype取值必须是:multipart/form-data。(默认是x-www-form-urlencoded)
- 提供一个文件选择域 < input type=“file” >
- multipart/form-data会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来说明文件类型;content-disposition,用来说明字段的一些信息;
由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件
- x-www-form-urlencoded:就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对,比如,name=Java&age = 23
2、JavaWeb传统方式的文件上传
- 导入文件上传的jar包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
- 编写文件上传的jsp页面
<h3>文件上传</h3>
<form action="fileupload" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload"><br/>
<input type="submit" value="提交">
</form>
- 编写文件上传的控制器
// 控制器类
@Controller
public class HelloController {
@RequestMapping("/fileupload")
public String findAccount(HttpServletRequest request) throws Exception{
System.out.println("accountId" + request.getMethod());
// 获取到要上传的文件目录
String path = request.getSession().getServletContext().getRealPath("/uploads");
System.out.println(request.getSession().getServletContext().getRealPath("/uploads"));
// 创建目录
File file = new File(path);
if (!file.exists()){
file.mkdir();
}
// 创建磁盘文件项工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// 解析request对象
List<FileItem> items = fileUpload.parseRequest(request);
for (FileItem item:items) {
//判断是普通字段还是上传文件
if (item.isFormField()){
//表单
}else{
//上传文件
String filename = item.getName();
item.write(new File(file, filename)); // 上传文件
item.delete(); // 删除临时文件
}
}
return "success";
}
}
3、SpringMVC文件上传
SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性名称相同。
- 编写文件上传的控制器
public class HelloController {
@RequestMapping("/fileupload")
public String findAccount(HttpServletRequest request, MultipartFile upload) throws Exception{
// 获取到要上传的文件目录
String path = request.getSession().getServletContext().getRealPath("/uploads");
// 创建目录
File file = new File(path);
if (!file.exists()){
file.mkdir();
}
// 获取到上传文件的名称
String filename = upload.getOriginalFilename();
String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
filename = uuid + "_" + filename;
//上传文件
upload.transferTo(new File(file, filename));
return "success";
}
}
- 配置文件解析器对象
<!-- 错误的配置 -->
<bean id="commonsMultipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxInMemorySize" value="10485760"></property>
</bean>
错误:
解决方法:
<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxInMemorySize" value="10485760"></property>
</bean>
4、SpringMVC跨服务器方式文件上传[待研究]
SpringMVC异常处理
1、异常处理思路
异常处理思路:Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet前端控制器找异常处理器进行异常处理。