spring mvc高级技术实例详解

 更新时间:2018年09月03日 14:34:37   作者:嗜血蚂蚁  
前面学习了简单的Spring Web知识,接着学习更高阶的Web技术。下面这篇文章主要给大家介绍了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中抛出异常。

总结:

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

相关文章

  • Java 生成二维码的工具资料整理

    Java 生成二维码的工具资料整理

    本文主要介绍Java 生成二维码的几种方法,这里给大家详细介绍了java生成二维码的三种工具,并附有示例代码供大家参考,开发java 二维码的朋友可以参考下
    2016-08-08
  • IDEA实现添加 前进后退 到工具栏的操作

    IDEA实现添加 前进后退 到工具栏的操作

    这篇文章主要介绍了IDEA 前进 后退 添加到工具栏的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • InvocationHandler中invoke()方法的调用问题分析

    InvocationHandler中invoke()方法的调用问题分析

    这篇文章主要介绍了InvocationHandler中invoke()方法的调用问题分析,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 在已经使用mybatis的项目里引入mybatis-plus,结果不能共存的解决

    在已经使用mybatis的项目里引入mybatis-plus,结果不能共存的解决

    这篇文章主要介绍了在已经使用mybatis的项目里引入mybatis-plus,结果不能共存的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Spring Data Elasticsearch使用方式(Elasticsearch)

    Spring Data Elasticsearch使用方式(Elasticsearch)

    这篇文章主要介绍了Spring Data Elasticsearch使用方式(Elasticsearch),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • java求数组最大值和最小数示例分享

    java求数组最大值和最小数示例分享

    这篇文章主要介绍了java求数组最大值和最小数示例,需要的朋友可以参考下
    2014-03-03
  • Spring Boot 条件注解详情

    Spring Boot 条件注解详情

    这篇文章主要介绍了Spring Boot 条件注解详情,SpringBoot条件注解@Conditional,可用于根据某个特定的条件来判断是否需要创建某个特定的Bean,下文更多相关介绍,需要的小伙伴可以参考一下
    2022-05-05
  • SpringMVC实现用户登录全过程

    SpringMVC实现用户登录全过程

    这篇文章主要介绍了SpringMVC实现用户登录全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • Jetty启动项目中引用json-lib相关类库报错ClassNotFound的解决方案

    Jetty启动项目中引用json-lib相关类库报错ClassNotFound的解决方案

    今天小编就为大家分享一篇关于Jetty启动项目中引用json-lib相关类库报错ClassNotFound的解决方案,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 利用java生成二维码工具类示例代码

    利用java生成二维码工具类示例代码

    二维码对现在的人们来说再熟悉不过了,我们在开发的时候也经常会用到二维码,下面这篇文章主要给大家介绍了关于利用java生成二维码工具类的相关资料,文中给了详细的示例代码,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09

最新评论