SpringMVC -- 梗概--贰
1.为什么要配置: mvc:annotation-driven
1>在springMVC的处理流程中,有两个重要组件:HandlerMapping和HandlerAdapter
分别负责解析Handler和执行Handler
2>如果配置了<mvc:annotation-driven/>,则在项目中自动注册:
RequestMappingHandlerMapping
RequestMappingHanderAdapter
且如上两个组件是对注解开发最新的最全面的支持
3>如果没有配置:<mvc:annotation-driven/>
则默认使用:
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter两个组件
而如上两组间已经弃用,且其对注解的支持并不全面,
比如@ResponseBody是不能被解析的。
*详细的springMVC流程:
2.静态资源的访问问题
配置:<mvc:default-servlet-handler/>
1>静态资源:除了Servlet、Controller之外的资源,如:js,css,png,html等
2>当请求静态资源:...xx/xx/xx.js,...xx/xx/xx.css,...xx/xx/xx.png等
如上请求会逐步回溯到【/】,即会进入DispatcherServlet,则会有HanderMapping
取查找Hanler,自然无法找到。此时如果没有如上配置,则404.
3>如果有如上配置,则在项目中会自动注册【/**】的一个handler,且此handler
会在最后映射请求,如果是项目中存在指定的静态资源,则会转向静态资源。
3.RestFul收参(了解) @PathVariable
1>定制方式:
//如下两个路径都可以访问到如下方法,请求路径不同,则name61和pwd61匹配到的值不同
//http://localhost:8989/appname/ful/lime/123
//http://localhost:8989/appname/ful/oracle/456
//@PathVariable("pwd61")-->获取路径中pwd61部分匹配到的值,并存入对应参数
@RequestMapping("/ful/{name61}/{pwd61}")
public String testMVC(@PathVariable("name61")String name,@PathVariable("pwd61")String password){
System.out.println("name:"+name+" password:"+password);
return "forward:/index.jsp";
}
*注意:所有的/ful/xx/xx的路径都可以访问到如上方法
2>细节:如果路径名 和 参数名 一致,则可以有省略写法,如下
@RequestMapping("/ful3/a{age}b/h{password}ilo")
public String testMVC3(@PathVariable Integer age,@PathVariable String password){
System.out.println("age:"+age+" password:"+password);
return "forward:/index.jsp";
}
*即【@PathVariable Integer age】将路径中名为age的部分匹配到的值存于age中
4.异常管理
4.1 定制异常管理器
public class MyExceptionResolver implements HandlerExceptionResolver{
/**
* 主体逻辑:自动捕获Controller中的异常,每当Controller中抛出异常时,就会执行。
* param:ex=当前抛出的异常
* req=请求对象
* res=响应对象
* handler=抛出异常的控制器方法
* 返回值:ModelAndView=用来返回错误页面
*/
public ModelAndView resolveException(HttpServletRequest req,
HttpServletResponse res, Object handler, Exception ex) {
ModelAndView mav=new ModelAndView();
//识别异常
if(ex instanceof LoginErrorException){
mav.setViewName("redirect:/error1.jsp");
}else if(...){}
...
return mav;
}
}
4.2 声明
<bean class="com.c61.ex.resolver.MyExceptionResolver"></bean>
4.3 异常管理器作用
作用:统一抽取了所有控制器中的异常处理逻辑
抽取前:
public String login(String username,String password){
try{
us.login(username, password);
}catch(LoginErrorException e){
return "redirect:/login.jsp";
}catch(AException e){
return "redirect:/xxx.jsp";
}catch(Exception e){
}
return "forward:/index.jsp";
}
抽取后:
public String login(String username,String password){
us.login(username,password);
return "forward:/index.jsp";
}
5.拦截器:Interceptor,抽取Controller中的冗余功能
5.1 定制
public class MyInterceptor implements HandlerInterceptor{
/**
* 在Controller之前执行(常用)
* 抽取Controller中的冗余功能
*/
public boolean preHandle(HttpServletRequest req, HttpServletResponse res,
Object handler) throws Exception {
//return false;//中断请求,则后续的controller,postHandle...都不再执行
//return true;//请求继续
if(xxx){
String path=req.getContextPath();
res.sendRedirect(path+"/index.jsp");//中断之前设置错误视图
return false;
}
return true
}
/**
* 在Controller之后,在响应之前,执行(了解)
* 可以做视图和数据的最终定制
*/
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView mav) throws Exception {
}
/**
* 在视图渲染完毕后执行(了解)
* 资源回收
*/
public void afterCompletion(HttpServletRequest req,
HttpServletResponse res, Object handler, Exception ex)
throws Exception {
}
}
5.2配置
<mvc:interceptors>
<mvc:interceptor>
<!-- 定义要拦截的路径 -->
<mvc:mapping path="/inter/test"/>
<mvc:mapping path="/inter/a"/>
<mvc:mapping path="/inter/b"/>
<!-- 声明拦截器 -->
<bean class="com.c61.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 定义要拦截的路径 -->
<mvc:mapping path="/inter/**"/>
<mvc:exclude-mapping path="/inter/test/**"/>
<!-- 声明拦截器 -->
<bean class="com.c61.interceptor.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
*注意:
1>当有多个拦截器同时拦截时,先配置的先拦截。如过Controller1 先后被inter1和inter2拦截,则具体的拦截路程为:
pre1==pre2==contorller==post2==post1==after2==after1
2>/* 只能匹配一级路径:/a /b /c /xxxxxx
. 却不能匹配:/a/b /e/d/c
/** 能匹配任意多级路径:/a /b /a/b/c /xxs/xxx/xxx/xx
3>mvc:exclude-mapping 不能单独使用,必须配合 mvc:mapping 使用
. 作用是在mvc:mapping的基础上排除一些路径
6.上传
6.1 定制上传表单
1>method="post"
2>enctype="multipart/form-data"
<form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/up/test">
<input type="file" name="file61"/>
<input type="submit" value="上传"/>
</form>
6.2 定制接收文件的Controller
public String testUP(MultipartFile file61,HttpSession s) throws IllegalStateException, IOException{
//file61.transferTo(new File("d:/abc/abc.txt"));
//获取虚拟路径:/up61 对应部署到服务器后的具体的磁盘路径
String realPath=s.getServletContext().getRealPath("/up61");
//获取文件名 xxx.txt xxx.png
String fileName=file61.getOriginalFilename();
//拼接写出路径
String path=realPath+File.separator+fileName;
//将文件写出到指定目录位置
file61.transferTo(new File(path));
return "forward:/index.jsp";
}
6.3 在springMVC容器中注册文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大允许的上传大小 byte -->
<property name="MaxUploadSize" value="2097152"></property>
</bean>
*ID必须为:multipartResolver
6.4 导包:commons-fileupload-1.3.jar commons-io-2.0.1.jar
6.5 生成唯一的文件名
//32长度 由16进制字符组成的全球唯一的字符串
UUID uuid=UUID.randomUUID();
System.out.println(uuid);
//uuid.toString()可以作为文件名使用,注意要拼接后缀
6.6 回显上传的图片
<!-- target="c61" 将响应展示在名为c61的iframe中(不再用一张新页面承载响应) -->
<form target="c61" method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/up/test">
<input type="file" name="file61"/>
<input type="submit" value="上传"/>
</form>
<iframe name="c61" width="200px" height="200px" frameborder="0"></iframe>
7.下载 (了解)
7.1 定制超链接
<a href="${pageContext.request.contextPath}/down/test?name=html教程全.ppt">免费下载</a>
7.2 定制下载的Controller
public String testDown(String name,HttpSession s,HttpServletResponse res) throws FileNotFoundException, IOException{
String path=s.getServletContext().getRealPath("/up61");
String filePath=path+File.separator+name;
//如果文件名中有中文:
String name2=URLEncoder.encode(name, "utf-8");
//设置响应头,实现附件形式下载文件(告知浏览器,需要以附件形式接收)
res.setHeader("content-disposition", "attachment;filename="+name2);
//输入流读取所有字节,输出流将所有读取到的字节写出
IOUtils.copy(new FileInputStream(filePath),res.getOutputStream());
return null;//如上语句,已经响应了请求,则必须return null;
}
8.验证码 见:第三阶段\springMVC\google_验证码\使用.txt
9.与spring集成
1>只是将代码累加在一起而已
2>当SpringMVC的Controller需要Spring的Service时,可以平行获取
3>唯一的注意点:防止容器之间相互污染
*容器污染防止手段:springMVC扫描控制机器相关组件,spring扫描剩余的
<context:component-scan base-package="com.c61">...
*解决方案一:use-default-filters="true"(true=默认值),则默认扫描所有的@Controller,@Service,@Repository
<context:component-scan base-package="com.c61" use-default-filters="true">
<!-- 排除某些注解,被排除的注解将不会扫描 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
. </context:component-scan>
. *解决方案二:use-default-filters="false" 不再主动扫描任何注解,在配合上include-filter,实现只扫描某个/些注解
<context:component-scan base-package="com.c61" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
SpringMVC -- 梗概--贰的更多相关文章
- SpringMVC -- 梗概--源码--贰--下载
1.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=&qu ...
- SpringMVC -- 梗概--源码--贰--上传
1.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=&qu ...
- SpringMVC -- 梗概--源码--贰--拦截器:Interceptor
附:实体类 1.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app versi ...
- SpringMVC -- 梗概--源码--贰--异常管理
附:实体类 Class : User package com.c61.entity; import java.text.SimpleDateFormat; import java.util.Date; ...
- SpringMVC -- 梗概--源码--贰--RestFul收参(了解) @PathVariable
1>定制方式: //如下两个路径都可以访问到如下方法,请求路径不同,则name61和pwd61匹配到的值不同 //http://localhost:8989/appname/ful/lime/1 ...
- SpringMVC -- 梗概--源码--贰--mvc:annotation-driven
1>在springMVC的处理流程中,有两个重要组件:HandlerMapping和HandlerAdapter 分别负责解析Handler和执行Handler 2>如果配置了<mv ...
- SpringMVC -- 梗概--源码--贰--静态资源的访问问题
配置:<mvc:default-servlet-handler/> 1>静态资源:除了Servlet.Controller之外的资源,如:js,css,png,html等 2> ...
- SpringMVC -- 梗概--壹
1.springMVC:MVC开源框架 2.springMVC开发流程: 2.1 导包: 2.2 配置前端控制器(核心) DispatcherServlet <servlet> <s ...
- SpringMVC -- 梗概--源码--壹--springMVC json处理
附:实体类 Class : User package com.c61.entity; import java.text.SimpleDateFormat; import java.util.Date; ...
随机推荐
- TCP三次握手四次挥手详解
转载 http://www.cnblogs.com/zmlctt/p/3690998.html 相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需 ...
- JAVA邮件发送的简单实现
JAVA MAIL是利用现有的邮件账户发送邮件的工具,比如说,我在网易注册一个邮箱账户,通过JAVA Mail的操控,我可以不亲自登录网易邮箱,让程序自动的使用网易邮箱发送邮件.这一机制被广泛的用在注 ...
- 快速掌握Flyway
什么是Flyway? Flyway is an open-source database migration tool. It strongly favors simplicity and conve ...
- SQL scripts
Add a column with default current date timeALTER TABLE [TableName]ADD CreatedOn DATETIME NOT NULL DE ...
- replace截取字段
var a = '123:'b = '123:disfkajsdhfjkasdhf'c = b.replace(a, '')"disfkajsdhfjkasdhf"
- c# AES加解密并转ASCII码
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Sec ...
- Leetcode: Nested List Weight Sum II
Given a nested list of integers, return the sum of all integers in the list weighted by their depth. ...
- VBA的打开关闭保存另存为等事件无法正常跑的原因
打开执行的代码需要写在thisworkbook的open事件下!!!!!如下图: VBA中事件分为三种:工作簿事件,工作表事件,窗体.控件事件. 工作簿事件发生在特定的工作簿中,如Open(打开工作簿 ...
- sysobjects中字段的含义
--列名 数据类型 描述 name sysname --对象名. Id int --对象标识号. xtype ) --对象类型.可以是下列对象类型中的一种: C = CHECK --约束 D = -- ...
- [Effective JavaScript 笔记]第64条:对异步循环使用递归
假设需要有这样一个函数,接收一个URL的数组并尝试依次下载每个文件直到有一个文件被成功下载.如果API是同步的,使用循环很简单实现. function downloadOneSync(urls){ f ...