javaweb-springMVC-55

2021-05-19 17:18:58 浏览数 (1)

文章目录

  • 内容大纲
  • 具体
    • 搭建环境
    • 第一章:响应数据和结果视图
      • 返回值分类
        • 返回字符串
        • 返回空
        • 返回值是ModelAndView对象
      • SpringMVC框架提供的转发和重定向
      • ResponseBody响应json数据
      • 通过json发送请求和接受
    • 第二章:SpringMVC实现文件上传
      • 必要条件:
      • 原理分析
      • 第三方组件封装
      • 解决
        • 传统文件上传。
      • SpringMVC传统方式文件上传
      • SpringMVC跨服务器方式文件上传
        • 新建服务
    • 第三章:SpringMVC的异常处理
      • 编写异常类
      • 编写处理器
      • 配置异常处理器srping.xml
    • 第四章:SpringMVC框架中的拦截器
      • 拦截器的概述
      • 拦截器
        • 配置拦截器
        • 拦截器类

内容大纲

项目地址:https://github.com/Jonekaka/javaweb-springMVC-55

具体

搭建环境

54上篇已经讲述

第一章:响应数据和结果视图

springmvc_day02_01_response

返回值分类

返回字符串

java

jsp

返回空
  1. 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。
  2. 默认会跳转到@RequestMapping(value=”/initUpdate”) initUpdate的页面。
  3. 可以使用请求转发或者重定向跳转到指定的页面 默认值:弱对应关系,返回sucess找sucess.jsp,返回void寻找testvoid.jsp 没有指定要寻找的界面,但是软件自己猜 java 之前的

修改后,指定要去调用哪个界面,产生强关联. 重定向两次请求,请求转发,一次请求,而且需要自己写完整路径,软件不猜了

jsp

返回值是ModelAndView对象
  1. ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图 和返回字符串的效果相同,但是写法不同,这个写法更为底层,返回字符串底层原理依赖此 最后都交给视图解析器解析 java

SpringMVC框架提供的转发和重定向

用关键字转发和重定向,用不了视图解析器,要写正确的路径

重定向需要写项目路径,这个底层已经加了,不用写 java

ResponseBody响应json数据

假如ajax异步请求,如何接受后台的json数据 前端控制器拦截 DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而 不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置 位置,文件路径(xx下不拦截谁)

通过json发送请求和接受

按键发送json请求 jsp 接受到后弹窗收到的内容 那么是否存在一种可能,将数据组自动json相互转化 导入jar包

java 获得请求体的内容,@RequestBody 这里已经自动将收到的json数据打包进user了 如果返回对象,前端默认的也是json,这里自动转化 以前还需要response写输出流,现在不必

第二章:SpringMVC实现文件上传

springmvc_day02_02_fileupload 导入文件上传的jar包

必要条件:

A form 表单的 enctype 取值必须是:multipart/form-data (默认值是:application/x-www-form-urlencoded) (—解释—:)【将整个表单分成几个部分,可能有的是文本框,有的是文件的内容等等】 enctype:是表单请求正文的类型 B method 属性取值必须是 Post (—解释—:)【如果是get,会把内容弄到地址栏上,有限制。】 C 提供一个文件选择域

原理分析

使用分隔符分成了若干部分 —————————–7de1a433602ac 分界符 Content-Disposition: form-data; name=“userName” 协议头 aaa 协议的正文 —————————–7de1a433602ac Content-Disposition: form-data; name=“file”; filename=“C:UserszhyDesktopfileupload_demofileb.txt” Content-Type: text/plain 协议的类型(MIME 类型) bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb —————————–7de1a433602ac– 然后取得内容写入就得到了文件

第三方组件封装

使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和 commons-io。commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它 工作时需要 commons-io 包的支持。

解决

创建工程时如果提示副工程,不需要关闭即可

导入坐标依赖

传统文件上传。

jsp

java 之所以删除临时文件,是因为上传文件>10k,就会生成临时文件,否则在内存中直接搞定 对于名字设定唯一值

代码语言:javascript复制
@RequestMapping("/fileupload1")
    public String fileuoload1(HttpServletRequest request) throws Exception {
   
        System.out.println("文件上传...");

        // 使用fileupload组件完成文件上传
        // 上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        // 判断,该路径是否存在
        File file = new File(path);
        if(!file.exists()){
   
            // 创建该文件夹
            file.mkdirs();
        }

        // 解析request对象,获取上传文件项
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 解析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传统方式文件上传

原理分析 解析request请求,交给文件解析器拿到上传的文件项信息,返回一个上传文件对象 自带的一个解析对象,通过参数绑定数据传送 解析器在spring.xml中配置

SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的 name属性名称相同。 spring.xml

代码语言:javascript复制
 <!--配置文件解析器对象-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760" />
    </bean>

jsp

代码语言:javascript复制
 <h3>Springmvc文件上传</h3>

    <form action="/user/fileupload2" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload" /><br/>
        <input type="submit" value="上传" />
    </form>

java

代码语言:javascript复制
/**
     * SpringMVC文件上传
     * @return
     */
    @RequestMapping("/fileupload2")
    //上传对象自带
    public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception {
   
        System.out.println("springmvc文件上传...");

        // 使用fileupload组件完成文件上传
        // 上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        // 判断,该路径是否存在
        File file = new File(path);
        if(!file.exists()){
   
            // 创建该文件夹
            file.mkdirs();
        }

        // 说明上传文件项,文件已经不需要自己解析了
        // 获取上传文件的名称
        String filename = upload.getOriginalFilename();
        // 把文件的名称设置唯一值,uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid "_" filename;
        // 完成文件上传
        upload.transferTo(new File(path,filename));

        return "success";
    }

SpringMVC跨服务器方式文件上传

在实际开发中,我们会有很多处理不同功能的服务器。例如: 应用服务器:负责部署我们的应用 数据库服务器:运行我们的数据库 缓存和消息服务器:负责处理大并发访问的缓存和消息 文件服务器:负责存储用户上传文件的服务器。 提高我们项目 的运行效率

新建服务

注意端口不要重复

java

代码语言:javascript复制
/**
     * 跨服务器文件上传
     * @return
     */
    @RequestMapping("/fileupload3")
    public String fileuoload3(MultipartFile upload) throws Exception {
   
        System.out.println("跨服务器文件上传...");

        // 定义上传文件服务器路径
        String path = "http://localhost:9090/uploads/";

        // 说明上传文件项
        // 获取上传文件的名称
        String filename = upload.getOriginalFilename();
        // 把文件的名称设置唯一值,uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid "_" filename;

        // 创建客户端的对象
        Client client = Client.create();

        // 和图片服务器进行连接
        WebResource webResource = client.resource(path   filename);

        // 上传文件
        webResource.put(upload.getBytes());

        return "success";
    }

jsp

代码语言:javascript复制
 <h3>跨服务器文件上传</h3>

    <form action="/user/fileupload3" method="post" enctype="multipart/form-data">
        选择文件:<input type="file" name="upload" /><br/>
        <input type="submit" value="上传" />
    </form>

第三章:SpringMVC的异常处理

springmvc_day02_03_exception

出现异常查看具体信息是开发者的事情,使用者不需要这么详细的信息

异常处理器调度异常界面,展示友好的异常信息 异常信息类,java,接受异常信息

编写异常类

代码语言:javascript复制
/**
 * 自定义异常类
 */
public class SysException extends Exception{
   

    // 存储提示信息的
    private String message;

    public String getMessage() {
   
        return message;
    }

    public void setMessage(String message) {
   
        this.message = message;
    }

    public SysException(String message) {
   
        this.message = message;
    }

}

ctrl alt T快速选择代码,然后环绕代码生成if else,try catch等 异常处理类

代码语言:javascript复制
 @RequestMapping("/testException")
    public String testException() throws SysException{
   
        System.out.println("testException执行了...");

        try {
   
            // 模拟异常
            int a = 10/0;
        } catch (Exception e) {
   
            // 打印异常信息
            e.printStackTrace();
            // 抛出自定义异常信息
            throw new SysException("查询所有用户出现错误了...");//就是刚才写的错误信息类,构造方法
        }



        return "success";
    }

编写处理器

继承接口,当有异常时检测到有处理器就交给处理器执行

代码语言:javascript复制
/**
 * 异常处理器
 */
public class SysExceptionResolver implements HandlerExceptionResolver{
   

    /**
     * 处理异常业务逻辑
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @return
     */
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
   
        // 获取到异常对象,判断类型是否符合,不符合就强转
        SysException e = null;
        if(ex instanceof SysException){
   
            e = (SysException)ex;
        }else{
   
            e = new SysException("系统正在维护....");
        }
        // 创建ModelAndView对象,这个是返回值,可以跳转页面

        ModelAndView mv = new ModelAndView();
        //存键值对
        mv.addObject("errorMsg",e.getMessage());
        //跳转页面,error.jsp
        mv.setViewName("error");
        return mv;
    }

配置异常处理器srping.xml

代码语言:javascript复制
 <!--配置异常处理器-->
    <bean id="sysExceptionResolver" class="cn.Learn_Java.exception.SysExceptionResolver"/>

第四章:SpringMVC框架中的拦截器

springmvc_day02_04_interceptor

拦截器的概述

  1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链 中的拦截器会按着定义的顺序执行。
  3. 拦截器和过滤器的功能比较类似,类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。有区别
    1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。 2. 拦截器是SpringMVC框架独有的。
    2. 过滤器配置了/*,可以拦截任何资源。 4. 拦截器只会对控制器中的方法进行拦截。如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的。
  4. 拦截器也是AOP思想的一种实现方式
  5. 想要自定义拦截器,需要实现HandlerInterceptor接口。

jsp

代码语言:javascript复制
<a href="user/testInterceptor" >拦截器</a>

java类

代码语言:javascript复制
@RequestMapping("/testInterceptor")
    public String testInterceptor(){
   
        System.out.println("testInterceptor执行了...");
        return "success";
    }

拦截器

继承接口后发现没有方法报错,那是因为他内部默认的方法已经默认实现了,如果不使用预制的可以重写 spring.xml

配置拦截器

先执行拦截器然后放行,否则

代码语言:javascript复制
 <!--配置拦截器-->
    <mvc:interceptors>
        <!--配置拦截器-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要拦截的方法,写一个就行,既然这个拦截了,其他的肯定不拦截,反之亦然
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置拦截器对象-->
            <bean class="cn.Learn_Java.controller.cn.Learn_Java.interceptor.MyInterceptor1" />
        </mvc:interceptor>

        <!--配置第二个拦截器-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/**"/>
            <!--不要拦截的方法,
            <mvc:exclude-mapping path=""/>
            -->
            <!--配置拦截器对象-->
            <bean class="cn.Learn_Java.controller.cn.Learn_Java.interceptor.MyInterceptor2" />
        </mvc:interceptor>
    </mvc:interceptors>
拦截器类

拦截器1,内部有三个方法,说明白,可以有多个拦截器 在这些类中,能够调用界面已经是最终的步骤,因此无返回拦截效果

不要奇怪,他们不是一起执行的,而是第一个拦截器确实已经执行完了,进入下一个,然后返回时发现条件又满足了继续一个个的拦截

代码语言:javascript复制
/**
 * 自定义拦截器
 */
public class MyInterceptor1 implements HandlerInterceptor{
   

    /**
     * 预处理,controller方法执行前
     * return true 放行,执行下一个拦截器,如果没有,执行controller中的方法
     * return false不放行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   
        System.out.println("MyInterceptor1执行了...前1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        return true;
    }

    /**
     * 后处理方法,controller方法执行后,只会拦截方法,success.jsp执行之前
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
   
        System.out.println("MyInterceptor1执行了...后1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
    }

    /**
     * success.jsp页面执行后,该方法会执行,优先级更低
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
   
        System.out.println("MyInterceptor1执行了...最后1111");
    }

}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100238.html原文链接:

0 人点赞