SpringMVC学习第二天(响应数据、文件上传、异常处理、拦截器)

一、SpringMVC响应数据

 1、响应之返回值为String、void、ModelAndView类型

  1.1 响应之返回值是String类型

Controller代码

	/**
	 * 返回值类型是String:底层代码就是使用ModelAndView对象进行存储、跳转等操作的
	 * @param model
	 * @return
	 */
	@RequestMapping("/testString")
	public String testString(Model model){
	    System.out.println("testString执行成功。。。。");
	    // 模拟从数据库中查询出User对象
	    User user = new User();
	    user.setUsername("张三丰");
	    user.setPassword("123");
	    user.setAge(50);
	    // model对象存数据,存储到了request域中了
	    model.addAttribute("user",user);
	    return "success";
	}

执行成功后跳转的success.jsp,直接通过EL表达式取Attribute中的值

<body>
    <h3>执行成功</h3>

    ${user.username}
    ${user.password}
    ${user.age}
</body>
  1.2 响应之返回值是void类型

Controller代码

/**
     * 返回值类型是void:默认请求/user/testVoid.jsp此页面
     *    请求转发是一次请求,不用编写项目的名称。
     * @param request
     */
    @RequestMapping("/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("testVoid执行成功。。。。");
        // 编写请求转发的程序
//        request.getRequestDispatcher("/WEB-INF/page/success.jsp").forward(request,response);
        // 编写重定向
//        response.sendRedirect(request.getContextPath()+"/index.jsp");
        // 设置中文乱码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        // 直接进行响应数据
        response.getWriter().print("hello啊!树哥");
        return; //终止后面代码执行
    }
  1.3 响应之返回值是ModelAndView类型
  ModelAndView对象的作用: 可以进行存储、跳转等操作的。

Controller代码

	/**
	 * 返回ModelAndView对象的方式:返回值为String的底层代码就是通过
	 * 	ModelAndView实现的。
	 * @return
	 */
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView(){
	    // 创建ModelAndView对象
	    ModelAndView mv = new ModelAndView();
	    System.out.println("testModelAndView执行成功。。。。");
	    // 模拟从数据库中查询出User对象
	    User user = new User();
	    user.setUsername("王二麻子");
	    user.setPassword("89784");
	    user.setAge(50);
	
	    // 将user对象存储到mv对象中,也会把user对象存储到request对象
	    mv.addObject("user",user);
	
	    // 跳转到哪儿个页面
	    mv.setViewName("success");
	    return mv;
	}

执行成功后跳转success.jsp,可直接通过EL表达式取出值

<body>
    <h3>执行成功!!!</h3>

    ${user.username}
    ${user.password}
    ${user.age}
</body>
  1.4 响应之使用关键字forward和redirect让页面跳转
	/**
     * 使用关键字的方式进行转发或者重定向
     * @return
     */
    @RequestMapping("/testForwardOrRedirect")
    public String testForwardOrRedirect(){
        System.out.println("testString执行成功。。。。");

        // 1、请求的转发:关键字的方式确定转发路径。
        return "forward:/WEB-INF/page/success.jsp";

        // 2、重定向:关键字方式无序使用request来获取项目名,进行拼接路径。
        return "redirect:/index.jsp";
    }

注意:路径问题问题,将webapp当做根目录进行书写,基本不会出错,实战中灵活变更。

 2、响应json数据之三步骤

  2.1 过滤静态资源

给springmvc.xml配置忽略过滤js静态文件夹下所有文件

	<!-- mvc:resources标签配置不过滤
	        1. location元素表示webapp目录下的包下的所有文件
	        2. mapping元素表示以/static开头的所有请求路径,如
	               /static/a 或者/static/a/b
	 -->
	<mvc:resources location="/js/" mapping="/js/**"/>
  2.2 发送ajax的请求
	// 1、导入Jquery的包
	<script src="js/jquery-3.5.1.js"></script>
	// 2、编写发送异步ajax代码
	<script>
	    $(function () {
	        $("#btn").click(function () {
	            // alert("123");
	            $.ajax({
	               // 编写json格式,设置属性和值
	               url:"user/testAjax",
	               contentType:"application/json;charset=UTF-8",
		data:'{"username":"U","password":"12","age":50}',
	               dataType:"json",
	               type:"post",
	               success:function (data) {
	                    // data:服务器端响应的json数据,进行解析
	                   alert(data);
	                   alert(data.username);
	                   alert(data.password);
	                   alert(data.age);
	               }
	            });
	        });
	    })
	</script>
  2.3 响应json格式数据

响应ajax请求,响应的数据格式需要在发送时通过dataType指定

	/**
	 * 模拟异步请求响应
	 *    @ResponseBody:将数据类型转换成ajax指定的json类型
	 *    @RequestBody:将ajax发送的json数据绑定到User对象中
	 */
	@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;
	}

二、文件上传

 1.原理分析与环境搭建

导入文件上传所需的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>

 2.传统方式上传方法回顾

JSP代码

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

Controller代码

	/**
	 * 传统的上传文件方式
	 * @return
	 */
	@RequestMapping("fileupload1")
	public String fileupload1(HttpServletRequest request) throws Exception {
	    System.out.println("文件上传。。。");
	
	    // 使用fileupload组件完成文件上传
	    // 上传的位置
	    String path = request.getSession().getServletContext().getRealPath("/uploads/");
	    System.out.println(path);
	    // 判断,该路径是否存在
	    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";
	}

 3.SpringMVC上传文件原理

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

SpringMVC上传文件原理

 4.SpringMVC上传文件代码实现

Controller代码

	/**
	 * SpringMVC上传文件方式
	 * @return
	 */
	@RequestMapping("fileupload2")
	public String fileupload2(HttpServletRequest request,MultipartFile upload) throws Exception {
	    System.out.println("文件上传。。。");
	
	    // 使用fileupload组件完成文件上传
	    // 上传的位置
	    String path = request.getSession().getServletContext().getRealPath("/uploads/");
	    System.out.println(path);
	    // 判断,该路径是否存在
	    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.xml代码

	<!--配置文件解析器-->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	    <property name="defaultEncoding" value="UTF-8"/>
	    <property name="maxUploadSize" value="5400000"/>
	</bean>

 5.跨服务器上传分析和搭建环境

原理分析图
原理分析图
pom.xml导入跨服务器上传所需jar包(坐标)

	<dependency>
	  <groupId>com.sun.jersey</groupId>
	  <artifactId>jersey-core</artifactId>
	  <version>1.18.1</version>
	</dependency>
	<dependency>
	  <groupId>com.sun.jersey</groupId>
	  <artifactId>jersey-client</artifactId>
	  <version>1.18.1</version>
	</dependency>

 6.跨服务器上传代码实现

Controller代码

	/**
	 * 跨服务器文件上传
	 * @return
	 */
	@RequestMapping("fileupload3")
	public String fileupload3(MultipartFile upload) throws Exception {
	    System.out.println("跨服务器文件上传。。。");
	
	    // 定义上传文件服务器路径
	    String path = "http://localhost:8080/fileupload/uploads/";
	
	    // 获取上传文件的名称
	    String filename = upload.getOriginalFilename();
	    // 把文件的名称设置唯一值:uuid
	    String uuid = UUID.randomUUID().toString().replace("-", "");
	    filename = uuid + "_" + filename;
	    // 创建客户端的对象
	    Client client = Client.create();
	    // 和图片服务器进行连接
	    WebResource resource = client.resource(path+filename);
	    // 上传文件(需要转换成字节数组上传)
	    resource.put(upload.getBytes());
	    return "success";
	}

注意:跨服务器上传出现的状态码为400、403、409错误在我的博客中有描述如何解决。

三、SpringMVC异常处理

 1.原理分析和环境搭建

原理分析和环境搭建

 2.异常处理代码编写

  2.1 编写自定义异常类(储存提示信息的)
public class SysException extends Exception {
  // 存储提示信息的
    private String massage;

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

    public String getMassage() {
        return massage;
    }

    public void setMassage(String massage) {
        this.massage = massage;
    }

}
  2.2 编写异常处理器

异常处理器

public class SysExceptionResolver implements HandlerExceptionResolver {
    /**
     * 处理异常业务逻辑
     * @param request
     * @param response
     * @param o
     * @param ex
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception ex) {
        // 获取到异常对象
        SysException se = null;
        if (ex instanceof SysException ){
            se = (SysException) ex;
        }else {
            se = new SysException("系统正在维护...");
        }
        // 创建ModelAndView对象:可以进行跳转页面
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",se.getMassage());
        mv.setViewName("error"); // 跳转到指定页面
        return mv;
    }
}
  2.3 配置异常处理器(跳转到指定页面)
<!--配置异常处理器对象-->
<bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolver"/>

四、SpringMVC拦截器

 1.作用介绍和环境搭建

拦截器原理图
拦截器原理图

过滤器与拦截器的区别:

  过滤器是servlet 规范中的一部分,任何java web 工程都可以使用。

  拦截器是SpringMVC 框架自己的,只有使用了SpringMVC 框架的工程才能用。

  过滤器在url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。

  拦截器它是只会拦截访问的控制器方法,如果访问的是jsp,html,css,image 或者js 是不会进行拦截的。

  总结:过滤器可用于所有web工程,可拦截所有资源。拦截器仅能拦截Controller类的方法,其他资源不会拦截,拦截器仅可用于SpringMVC框架!

 2.编写controller

Controller代码

public class UserController {
    /**
     * 1、编写拦截器类,实现HandlerInterceptor
     * 2、配置拦截器
     * @return
     */
    @RequestMapping("testInterceptor")
    public String testInterceptor() {
        System.out.println("testInterceptor执行了。。。。");
        return "success";
    }
}

 3.创建拦截器类

  注意:拦截器中可重定向和请求转发跳转页面,通过了解jsp、Controller、拦截类的执行顺序时,即可完美使用拦截器对程序进行完善。

/**
 * 自定义拦截器:当拦截器有多个时,先走拦截范围小的拦截器,再走大的。
 * @author Vagaband
 * @date 2020/5/25 14:10
 */
public class MyInterceptor1 implements HandlerInterceptor {
    /**
     * 预处理,controller方法执行前走它
     *    return true; 放行,执行下一个拦截器,如果没有,执行controller中的方法
     *    return false; 不放行
     *    作用:可用于判断用户是否登录等功能。。。
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor1执行了。。。前111111");
//        request.getRequestDispatcher("/WEB-INF/page/error.jsp").forward(request,response);
        return true;
    }

    /**
     * 后处理的方法,controller方法执行后,success.jsp执行之前会执行此方法。
     *     作用:用于方法执行之后判断用户是否正确等。。
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor1执行了。。。后111111");
        //request.getRequestDispatcher("/WEB-INF/page/error.jsp").forward(request,response);
    }

    /**
     * success.jsp页面执行后,该方法会执行
     *    作用:可用于释放资源等。。
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor1执行了。。。最后111111");
    }
}

 4、配置拦截器

Springmvc.xml配置代码

	<!--配置拦截器1-->
    <mvc:interceptors>
        <!--配置拦截器-->
        <mvc:interceptor>
            <!--要拦截的具体的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要拦截的方法-->
<!--            <mvc:exclude-mapping path=""/>-->
            <!--配置拦截器的对象-->
            <bean class="cn.itcast.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>

 5.多个拦截器时代码的执行顺序

  要点: 当有多个拦截器时,先执行拦截范围小的拦截器,再执行拦截范围大的拦截器,使用多个拦截器时需要时刻注意拦截顺序,否则脑袋一团浆糊。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值