三层架构:
表现层(SpringMVC):也就是我们常说的web层,它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求web层,web需要接收Http请求,完成http响应
业务层(Spring):也就是我们常说的service层,它负责业务逻辑处理
持久层(myBatis):数据持久化,包括数据层即数据库和数据访问层
SpringMVC:
使用Meavn依赖导入
入门案例流程:
1.启动服务器,加载一些配置文件:
- DispatcherServlet对象创建
- springmvc.xml被加载了
- HelloController创建成对象
2.发送请求,后台处理请求
SpringMVC框架基于组件方式执行流程:
<mvc:annotation-driven/>
说明:
在SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件
使用mvc:annotation-driven 自动加载RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter(处理适配器),可用在SpringMVC.xml配置文件中使用mvc:annotation-driven 替代注解处理器和适配器的配置
RequestMapping注解的作用:
value:用于指定请求的URL,它和Path属性的作用是一样的
method:用于指定请求的
param:用于指定限制请求参数的条件,它支持简单的表达式,要求请求参数的key和value必须和配置的一模一样
headers:用于指定限制请求消息头的条件
请求参数绑定:
//请求参数绑定
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/testParam")
public String testParam(){
System.out.println("执行了...");
return "success";
}
//请求参数绑定把数据封装到JavaBean的类中
@RequestMapping("/savaAccount")
public String saveAccount(Account account){
System.out.println("执行了...");
System.out.println(account);
return "success";
}
}
自定义类型转换器代码:
<!--配置自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<!--注册一个自定义转换器-->
<bean class="cn.itcast.utils.StringToDateConverter"></bean>
</set>
</property>
</bean>
将类型转换器配置生效:
<mvc:annotation-driven conversion-service="conversionService"/>
获取Servlet原生API
@RequestMapping("/testServlet")
常用注解:
@RequestParam 获取请求参数
@RequestBody 获取请求体内容,get请求不适用
@PathVariable 用于绑定Url中的占位符
@RequestMapping("/testPathVariable/{sid}")
public String testPathVariable(@PathVariable(name = "sid") String id){
System.out.println("执行了");
System.out.println(id);
return "success";
}
使用时后面直接加id的值
<a href="/anno/testPathVariable/10">RequestParam</a>
@RequestHeader 获取指定请求头的值
@CookieValue 获取指定cookie的名称的值
@ModelAttribute 在SpringMVC4.3版本以后新加入的,它可以用于修饰方法和参数
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行,它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法
出现在参数上,获取指定的数据给参数赋值
应用场景:可以给没有赋值的数据,赋值数据库的默认值
@SessionAttribute 用于多次执行控制器方法间的参数共享
可以把数据存取、删除
响应:
返回值是void,string,modelandview对象
ModelAndView对象是SpringMVC为我们提供的一个对象,该对象也可以用作控制器方法的返回值
ModelAndView mv = new ModelAndView();
//把user对象存储到mv对象中,也会把user对象存入到request对象
mv.addObject("user",user);
//跳转到哪个页面,使用视图解析器
mv.setViewName("success")
使用关键字的方式进行转发和重定向:(使用关键字时不能使用视图解析器)
@RequestMapping("/testForwardOrRedirect")
public String testForwardOrRedict(){
System.out.println("testForwardOrRedirect方法执行了");
//请求的转发
// return "forward:/WEB-INF/pages/success.jsp";
//重定向
return "redirect:/index.jsp"; //不用带项目名,框架默认加上
}
ResponseBody响应json数据:
<!--前端控制器,哪些静态资源不拦截-->
<mvc:resources mapping="/css" location="/css/**" />
<mvc:resources mapping="/images" location="/images/**" />
<mvc:resources mapping="/js" location="/js/**" />
响应json数据发送ajax请求
//模拟异步请求响应
@RequestMapping("/testAjax")
public void testAjax(@RequestBody String body){
System.out.println("testAjax方法执行了");
System.out.println(body);
}
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax方法执行了");
//客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中
System.out.println(user);
//做响应,模拟查询数据库
user.setUsername("haha");
user.setAge(40);
//做响应
return user;
}
SpringMVC实现文件上传:
文件上传的必要前提:
1.form表单的enctype取值必须是:Multipart/form-data
2.method属性取值必须是Post
3.提供一个文件选择域
传统文件上传:
使用commons-fileupload组件实现文件上传:
<form class="/user/fileupload" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload"> </br>
<input type="submit" value="上传" />
</form>
@RequestMapping("/fileupload1")
public String fileupload(HttpServletRequest request){
System.out.println("文件上传");
//使用fileupload组件完成文件上传
//上传位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
//判断,该路径是否存在
File file = new File(path);
if (!file.exists()){
//创建该文件夹
file.mkdir();
}
//解析request对象,获取上传文件项
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload();
//解析request
List<FileItem> items = upload.parseRequest(request);
//遍历
for (FileItem item:items){
//判断当前Item对象是否是上传文件项
if (item.isFormField()){
//说明普通表单项
}else {
//说明上传文件项
//获取上传文件的名称
String filename = item.getName();
//把文件的名称设置唯一值:uuid
String uuid = UUID.randomUUID().toString().replace("-","");
filename = uuid + "_" + filename;
//完成文件上传
item.write(new File(path,filename));
//删除临时文件
item.delete();
}
}
return "success";
}
Springmvc文件上传:
1.
<!--配置文件解析器对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485768" />
</bean>
Springmvc跨服务器方式的文件上传:
在实际开发中,我们会有很多处理不同功能的服务器:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
缓存和消息服务器:负责处理大并发访问的缓存和消息
文件服务器:负责存储用户上传文件的服务器
@RequestMapping("/fileupload3")
public String fileupload(MultipartFile upload){
System.out.println("跨服务器文件上传...");
//定义上传文件服务器路径
String path = "http://localhost:8080/uploads/";
//说明上传文件项
//获取上传文件的名称
String filename = upload.getOriginalFilename();
//把文件的名称设置唯一值:uuid
String uuid = UUID.randomUUID().toString().replace("-","");
filename = uuid + "_" + filename;
//创建客户端的对象
Client client = Client.create();
//和图片服务器进行连接
WebReasource webReasource = client.resource(path + filename);
//上传文件
webReasource.put(upload.getBytes());
return "success";
}
SpringMVC的异常处理:
SpringMVC的处理器拦截器类似Servlet开发中的过滤器Filter:用于对处理器进行预处理和后处理
过滤器和拦截器的区别:
过滤器是Servlet规范中的一部分,任何java web工程都可以使用,在url-pattern中配置了/*之后,可以对所有要访问的资源拦截
拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用,它只会拦截访问的控制器方法,如果访问的是jsp,html,css,image或者js是不会进行拦截的
第一步:拦截方法:
//预处理,controller方法执行前 return
// true放行,执行下一个拦截器,如果没有,执行controller中的方法
// return false 不发行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行了");
return false;
}
第二步:配置拦截器:
<mvc:interceptors>
<!--配置拦截器-->
<mvc:interceptor>
<!--要拦截的具体方法-->
<mvc:mapping path="/user/*"/>
<!--不要拦截的方法-->
<!-- <mvc:exclude-mapping path=""/>-->
<!--配置拦截器对象-->
<bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
拦截器接口方法:
//后处理方法,controller方法执行后,success.jsp执行之前
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("执行了...后");
request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
}
//success.jsp执行后,该方法会执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("执行了...最后");
}