zoukankan      html  css  js  c++  java
  • 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.验证码 见:第三阶段springMVCgoogle_验证码使用.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>
  • 相关阅读:
    iOS 文件操作--归档和解档
    iOS中UITabBarController的使用
    Objective-C基础知识点总结,字符串操作,数组操作,字典操作
    Objective-C中协议和分类总结
    Objective-C文件操作之NSCoding协议之小练习
    浅谈Objective-C继承和多态
    Objective-C内存管理基础知识
    MySort(选做)的实现
    20175308 2018-2019-2 实验四 《Android开发基础》实验报告
    JAVA 第十一周学习总结
  • 原文地址:https://www.cnblogs.com/ClassNotFoundException/p/6046759.html
Copyright © 2011-2022 走看看