spring mvc高级技术实例详解

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";
 }
}

异常测试

在controller、service、dao中任意一处需要手动抛出异常。

如果是程序中手动抛出的异常,在错误页面中显示自定义的异常信息,如果不是手动抛出异常说明是一个运行时异常,在错误页面只显示“未知错误”。

在商品修改的controller方法中抛出异常 .

在service接口中抛出异常:

如果与业务功能相关的异常,建议在service中抛出异常。

与业务功能没有关系的异常,建议在controller中抛出。

上边的功能,建议在service中抛出异常。

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • SpringMVC文件上传 多文件上传实例

    必须明确告诉DispatcherServlet如何处理MultipartRequest.SpringMVC中提供了文件上传使用方式如下配置xxx-servlet.xml,添加如下代码: 复制代码 代码如下: <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">          <!-- 设置

  • springMVC几种页面跳转方式小结

    前面已经了解了Controller的几种配置方式 今天主要写一下响应界面跳转的几种方式 1.在注解的方式中 1.1通过HttpServletResponse的API直接输出(不需要配置渲染器) controller类的主要代码 @Controller public class RequestController{ @RequestMapping("/resp") public void handleRequest(HttpServletRequest req, HttpServletR

  • SpringMVC拦截器实现登录认证

    博客以Demo的形式讲诉拦截器的使用 项目结构如图: 需要的jar:有springMVC配置需要的jar和jstl需要的jar SpringMVC包的作用说明: aopalliance.jar:这个包是AOP联盟的API包,里面包含了针对面向切面的接口.通常spring等其它具备动态织入功能的框架依赖这个jar spring-core.jar:这个jar 文件包含Spring 框架基本的核心工具类.Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统

  • SpringMVC之简单的增删改查示例(SSM整合)

    虽然已经在做关于SpringMVC的项目.但是还没有写一些比较系统的博客.今天就先来说一说最简单的增删改查吧.这个例子是基于SpringMVC+Spring+Mybatis实现的. 环境配置 主要是几项配置:springmvc的配置,spring的配置,MyBatis的配置,jdbc的配置,和web.xml配置 springmvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu

  • spring mvc高级技术实例详解

    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> <

  • Spring MVC的文件下载实例详解

    Spring MVC的文件下载实例详解 读取文件 要下载文件,首先是将文件内容读取进来,使用字节数组存储起来,这里使用spring里面的工具类实现 import org.springframework.util.FileCopyUtils; public byte[] downloadFile(String fileName) { byte[] res = new byte[0]; try { File file = new File(BACKUP_FILE_PATH, fileName); i

  • Spring MVC全局异常实例详解

    目录 无SpringMVC全局异常时的流程图 SpringMVC全局异常流程图 其实是一个ModelAndView对象 配置文件 applicationcontext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.

  • Spring Cloud Feign高级应用实例详解

    这篇文章主要介绍了Spring Cloud Feign高级应用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.使用feign进行服务间的调用 Spring boot2X Consul如何使用Feign实现服务调用 2.开启gzip压缩 Feign支持对请求与响应的压缩,以提高通信效率,需要在服务消费者配置文件开启压缩支持和压缩文件的类型 添加配置 feign.compression.request.enabled=true feig

  • spring mvc路径匹配原则详解

    在Spring MVC中经常要用到拦截器,在配置需要要拦截的路径时经常用到<mvc:mapping/>子标签,其有一个path属性,它就是用来指定需要拦截的路径的.例如: <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.i360r.platform.webapp.runtime.view.interceptor.GenericInterceptor"

  • AngularJS tab栏实现和mvc小案例实例详解

    tab栏: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tab 标签</title> <style> body { margin: 0; padding: 0; background-color: #F7F7F7; } .tabs { width: 400px; margin: 3

  • Spring boot 使用mysql实例详解

    Spring boot 使用mysql实例详解 开发阶段用 H2即可,上线时,通过以下配置切换到mysql,spring boot将使用这个配置覆盖默认的H2. 1.建立数据库: mysql -u root CREATE DATABASE springbootdb 2.pom.xml: <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId&g

  • vue 组件高级用法实例详解

    一.递归组件 组件在它的模板内可以递归地调用自己, 只要给组件设置name 的选项就可以了. 示例如下: <div id="app19"> <my-component19 :count="1"></my-component19> </div> Vue.component('my-component19',{ name: 'my-component19', //其实当你利用 Vue.component 全局注册了一个组件

  • Java Spring MVC获取请求数据详解操作

    目录 1. 获得请求参数 2. 获得基本类型参数 3. 获得POJO类型参数 4. 获得数组类型参数 5. 获得集合类型参数 6. 请求数据乱码问题 7. 参数绑定注解 @requestParam 8. 获得Restful风格的参数 9. 自定义类型转换器 1.定义转换器类实现Converter接口 2.在配置文件中声明转换器 3.在<annotation-driven>中引用转换器 10. 获得Servlet相关API 11. 获得请求头 11.1 @RequestHeader 11.2 @

  • Spring Boot 整合 Reactor实例详解

    目录 引言 1 创建项目 2 集成 H2 数据库 3 创建测试类 3.1 user 实体 3.2 UserRepository 3.3 UserService 3.4 UserController 3.5 SpringReactorApplication 添加注解支持 测试 总结 引言 Reactor 是一个完全非阻塞的 JVM 响应式编程基础,有着高效的需求管理(背压的形式).它直接整合 Java8 的函数式 API,尤其是 CompletableFuture, Stream,还有 Durat

随机推荐