Spring MVC高级技术包括但不限于web.xml配置、异常处理、跨重定向请求传递数据

1、web.xml文件的配置

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> </web-app>

  ContextLoaderListener是根容器,DispatcherServlet是子容器。父容器中管理的bean可以被子容器引用,反之,不行。它们都从各自的xml文件初始化自己的上下文

  ContextLoaderListener如果未指定contextConfigLocation参数,则默认加载的配置文件为/WEB-INF/applicationContext.xml

  DispatcherServlet如果未指定contextConfigLocation参数,则根据<servlet-name>元素指定的名称,在/WEB-INF/文件夹下寻找配置文件appServlet-servlet.xml

2、处理异常

Spring提供了多种方式将异常转换为响应

  • 特定的 Spring异常会自动映射为指定的HTTP状态码
  • 异常上可以添加@ResponseStatus注解,将异常映射为某一个HTTP状态码
  • 在方法上可以添加@ExceptionHandler注解,使其用来处理异常

1)特定的 Spring异常会自动映射为指定的HTTP状态码

  如果在控制器中抛出了异常,该异常不在列表中,又没有指定HTTP状态码,则默认为状态码为500

2)异常上可以添加@ResponseStatus注解,将异常映射为某一个HTTP状态码

@Controller
public class HelloController { @RequestMapping("/home")
public String home(){
System.out.println("执行home");
throw new MyException();
// return "home"; //返回一个字符串,即逻辑视图名
}
}
package com.cn.Exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
public class MyException extends RuntimeException{ }

浏览器访问 http://localhost:8080/home

修改自定义异常

package com.cn.Exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "抛出异常的原因")
public class MyException extends RuntimeException{ }

浏览器访问 http://localhost:8080/home

3)在方法上可以添加@ExceptionHandler注解,使其用来处理异常

  • 该方式是按照处理请求的方式处理异常,@ExceptionHandler注解的方法返回值为字符串表示逻辑视图名
package com.cn.Exception;

public class MyException2 extends RuntimeException{

}
@Controller
public class HelloController { @RequestMapping("/home")
public String home(){
System.out.println("执行home");
throw new MyException2();
// return "home"; //返回一个字符串,即逻辑视图名
} @ExceptionHandler(MyException2.class)
public String handleMException(){
System.out.println("处理异常逻辑");
return "fail";
}
}

访问http://localhost:8080/home,后台输出

浏览器页面

@ExceptionHandler注解的方法可以处理同一个控制器中所有处理器方法所抛出的异常(注解指定的异常),注解定义如下

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
Class<? extends Throwable>[] value() default {};
}
  • spring也支持为控制器添加通知,那么该通知对于所有的控制器中所有的处理器方法抛出的异常都起作用,实现如下

  @ControllerAdvice 所标注的类会被组件扫描实例化,交给容器管理。最为实用的一个场景是将所有@ExceptionHandler标注的方法收集到一个类中,这样所有的控制器异常就能在一个地方进行一致处理。以下HandleException类定义表明在控制器中的处理器抛出MyException2类的异常,就会被handleMException方法处理,最终跳转fail.jsp页面

package com.cn.advice;

import com.cn.Exception.MyException2;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice
public class HandleException { @ExceptionHandler(MyException2.class)
public String handleMException(){
System.out.println("处理异常逻辑");
return "fail";
} }

3、跨重定向请求传递数据

  如果是forward转发请求,那么处理器方法业务处理完成后,该方法所指定的模型数据会复制到请求中,作为请求的一部分,转发到下一个处理器,下一个处理器可以从请求中获取上一个处理的模型数据;

  如果是redirect重新向,原始请求就结束了,并且会重新发起一个GET请求。因此原始请求中的模型数据也就消失了,在请求到达下一个处理器,没有任何的模型数据,需要模型数据必须自己处理。

针对重定向传递数据,有两种方案:

  • 使用URL模板以路径变量和/或查询参数的形式传递数据
  • 使用flash属性传递数据

1)使用URL模板以路径变量和/或查询参数的形式传递数据

@Controller
public class HelloController { @RequestMapping("/home2")
public String home2(Model model){
model.addAttribute("id","12324131343256");
model.addAttribute("name","pick");
return "redirect:home3/{id}"; //含有redirect的字符串,表示重定向到另一个处理器;
//如果含有forward的字符串,表示转向到另一个处理器
} @RequestMapping("/home3/{id}")
public String home3(@PathVariable String id, Model model){
System.out.println("传递的ID="+id);
model.addAttribute(new User());
return "home";
}
}

  浏览器访问localhost:8080/home2,抓包得访问的url。从以下可以看出,处理器完成后重定向时,模型中的数据填充到了路径变量中,路径变量中没有的key,则以查询参数的形式赋在url之后,组成了新的url访问。

2)使用flash属性传递数据

  重定向时候,采用1)中的方式传递数据,仅仅能够传递简单的数据,不能传递对象。如何将对象也能传递到下一个处理器呢?可以将要传递到下一个处理器的数据放入用户会话中,然后在下一个处理器从会话的取出来,并删除会话中的该数据。然而,spring提供了将数据发送为flash属性的功能,不需要我们管理这些数据,flash属性会一致携带这些数据直到下一次请求才消失。

  Spring提供RedirectAttributes是Model接口的子接口,除了提供Model的所有功能,还提供了几个方法用来设置flash属性。

@Controller
public class HelloController { @RequestMapping("/home2")
public String home2(RedirectAttributes model){
model.addAttribute("id","12324131343256");
model.addFlashAttribute("user",new User("liming","123456"));//设置flash属性,也可以 model.addFlashAttribute(new User("liming","123456"))
                                       //则通过值得类型自行推断出key为user
return "redirect:home3/{id}";
} @RequestMapping("/home3/{id}")
public String home3(@PathVariable String id, RedirectAttributes model){
System.out.println("传递的ID="+id);
if (model.containsAttribute("user")) {
System.out.println("传递的对象:" + model.getFlashAttributes().get("user"));
}
return "home";
}
}

spring-mvc高级技术的更多相关文章

  1. 【Spring】Spring MVC高级技术

    前言 前面学习了简单的Spring Web知识,接着学习更高阶的Web技术. 高级技术 Spring MVC配置的替换方案 自定义DispatcherServlet配置 在第五章我们曾编写过如下代码. ...

  2. 七、Spring MVC高级技术

    知识点 处理文件上传 使用flash属性 在控制器中处理异常 关键词 控制器通知 (Controller Advice) 7.1 处理异常 Spring提供了多种方式将异常转换为响应: 特定的Spri ...

  3. Spring MVC(3)Spring MVC 高级应用

    一.Spring MVC 的数据转换和格式化 前面的应用,都只是用HandlerAdapter去执行处理器. 处理器和控制器不是一个概念,处理器是在控制器功能的基础上加上了一层包装,有了这层包装,在H ...

  4. spring MVC框架入门(外加SSM整合)

    spring MVC框架 一.什么是sping MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 W ...

  5. Java方式配置Spring MVC

    概述 使用Java方式配置Spring MVC,以及回顾一下Spring MVC的各种用法. Spring MVC简述 关于Spring MVC的介绍网上有很多,这里就不再赘述了,只是要说一下,Spr ...

  6. 第07章-Spring MVC 的高级技术

    Spring MVC 的高级技术 1. Spring MVC配置的替代方案 1.1 自定义DispatcherServlet配置 AbstractAnnotationConfigDispatcherS ...

  7. Spring学习(七)--Spring MVC的高级技术

    一.Spring MVC配置的替代方案 我们已经了解如何通过AbstractAnnotationConfigDispatcherServlet- Initializer快速搭建了Spring MVC环 ...

  8. 笔记34 Spring MVC的高级技术——处理multipart形式的数据

    一.需求介绍: Spittr应用在两个地方需要文件上传.当新用户注册应用的时候,我 们希望他们能够上传一张图片,从而与他们的个人信息相关联.当用 户提交新的Spittle时,除了文本消息以外,他们可能 ...

  9. 笔记33 Spring MVC的高级技术——Spring MVC配置的替代方案

    一.自定义DispatcherServlet配置  AbstractAnnotationConfigDispatcherServletInitializer所完成 的事情其实比看上去要多.在Spitt ...

随机推荐

  1. Best Time to Buy and Sell Stock II--疑惑

    https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 代码如下时能AC class Solution { publi ...

  2. 关于单一网络适配器拓扑TMG

    单网络适配器拓扑的功能 在单网络适配器拓扑中可以实现有限的 Forefront TMG 功能,其中包括: 针对 HTTP.HTTPS 和 CERN 代理 FTP 的正向 (CERN) 代理(仅限下载) ...

  3. EJB 3.1 @Startup @Singleton sequence

    The annotation javax.ejb.Startup (@Startup) is used to mark an EJB so to make the EJB can be brought ...

  4. 如何写Paper

    如何写文章,如何写好文章,是每一个科研工作者想弄懂或者已经弄懂了的问题.剑桥大学某研究人员分享了他的写作思路. 我从该视频中学到了以下几点经验: 正确的顺序是:Idea——>Write——> ...

  5. redis在windows平台安装和启动

    官网: https://redis.io/ 中文网站:http://www.redis.net.cn/ 一.下载windows版本的redis 官网没有提供windows版本的下载,只有linux版本 ...

  6. sqlite3如何退出...>状态

    一般是进入SQL数据语言模式了,此时要想退出...>状态,只要输入一条完整的SQL语句就行了,也就是末尾要加上:(分号)这个符号就可以退回到sqlite>状态

  7. reactnative 原生组件通信原理

    http://www.csdn.net/article/2015-11-27/2826345-compare-React-Native-with-ExMobi 原生组件通信原理 React Nativ ...

  8. thinkphp5.0查询到的数据表中的路径是反斜杠导致无法正常显示图片怎么办?

    添加到数据表中图片的路径有时会是反斜杠,这就导致了在url后面写路径的时候会识别不出来(不过src后面写路径就可以识别),所以就需要把路径中的反斜杠替换成正斜杠,代码如下: $datu = Db::q ...

  9. IDEA定位开发文件在左边工程中的文件路径

    IDEA新公司入职使用第七天,基本快捷键和BUG调试已经搞透了!从最开始的配置到现在的适应确实是一个不小的进步,前几天每天加班太忙没有时间更新博客,明天就是五一假期,现在将刚掌握的一点IDEA技术写出 ...

  10. Eclipse安装Sonarlint插件

    这里安装的是Sonarlint3.6.插件安装非常简单.插件比Sonar更为简单快捷. 一.首先通过点击Eclipse上方Help菜单会出现一个下拉列表,点击其中的Eclipse MarketPlac ...