SpringMVC(二)响应数据和异常处理

一、响应数据

1.1 返回类型为字符串

  • Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。
    示例:在index.jsp点击链接,跳转到success.jsp页面
/*********************index.jsp**********************/
<a href="test/testReturnString">testReturnString</a>

/****************TestResponse.java*******************/
@Controller
@RequestMapping("/test")
public class TestResponse {
	//指定逻辑视图名,经过视图解析器解析为 jsp 物理路径:/WEB-INF/pages/success.jsp 
    @RequestMapping("/testReturnString")
    public String testReturnString(){
        System.out.println("testReturnString方法执行了");
        return "success";
    }
}

运行结果:
在这里插入图片描述

1.2 返回类型为void

  • 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。默认会跳转到@RequestMapping(value="/XXX") XXX的页面。
/*********************index.jsp**********************/
<a href="/test/testVoid">testVoid</a><br/>

/****************TestResponse.java*******************/
    @RequestMapping("/testVoid")
    public void testVoid(){
        System.out.println("testVoid方法执行了");
    }

运行结果:
在这里插入图片描述
但是可以以Servlet原始API作为控制器中方法的参数,使用请求转发或者重定向跳转到指定的页面。

    @RequestMapping("/testvoid")
    public void testvoid(HttpServletRequest request, HttpServletResponse response) throws Exception{
        // 设置中文乱码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //第一种:请求转发
        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
       //第二种:重定向
        response.sendRedirect("testReturnString");
        //第三种:直接响应
        response.getWriter().print("testAdd执行了");
    }

1.3 返回类型为ModelAndView

  • ModelAndView对象是Spring提供的一个对象,该对象可以用作控制器方法的返回值,可以用来调整具体的JSP视图 。
/*********************index.jsp**********************/
<a href="test/testModelAndView">testModelAndView</a><br/>
/****************TestResponse.java*******************/
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView() throws Exception{
        ModelAndView mv = new ModelAndView();
        User user = new User();
        user.setUname("叶子");
        user.setAge(21);
        // 把user对象存储到mv对象中,也会把user对象存入到request对象
        mv.addObject(user);
        // 用于设置逻辑视图名称,视图解析器会根据名称前往指定的视图
        mv.setViewName("success");
        return mv;
    }
/****************success.jsp*******************/
    对象:${user}<br/>
    姓名:${user.uname}

运行结果:
在这里插入图片描述

1.4 响应json数据

  • SpringMVC中可以使用@ResponseBody注解响应json数据,该注解将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据,通过response响应给客户端
      Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要加入 jackson 的包。
	<!---------------pom.xml--------------->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>

/*********************index.jsp**********************/
    <script>
    // 页面加载,绑定单击事件
        $(function () {
            $("#btn").click(function () {
                $.ajax({
                    url:"test/testAjax",
                    type:"post",
                    dataType:"json",
                    contentType:"application/json;charset=UTF-8",
                    data:'{"uname":"叶子","age":21}',
                    success:function (data) {
                        alert(data+"---"+data.uname);
                    }
                })
            })
        })
    </script>
/****************TestResponse.java*******************/
    @RequestMapping("/testAjax")
    public @ResponseBody User testAjax(@RequestBody User user){
        System.out.println(user);
        return user;
    }

运行结果:
在这里插入图片描述

1.5 转发与重定向

  • controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。
    转发:
      “forward:url” ,不走视图解析器了,所以需要编写完整的路径 ,它相当于request.getRequestDispatcher(“url”).forward(request,response),使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法。
    重定向:
      “redirect:url” ,它相当于“response.sendRedirect(url)”。
    需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不 能写在 WEB-INF 目录中,否则无法找到。
/*********************index.jsp**********************/
<a href="test/testForwardOrRedirect">testForwardOrRedirect</a>
/****************TestResponse.java*******************/
    @RequestMapping("/testForwardOrRedirect")
    public String testForwardOrRedirect(){
        // 请求转发
        return "forward:/WEB-INF/pages/success.jsp";
        // 重定向
        return "redirect:testModelAndView";
    }

二、异常处理

  • 系统中异常包括两类:预期异常和运行时异常 RuntimeException,前者通过捕获异常从而获取异常信息, 后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
  • 系统的 dao、service、controller 出现都通过 throws Exception 向上抛出,最后由 springmvc 前端 控制器交由异常处理器进行异常处理,如下图:
    在这里插入图片描述
  • 2.1 使用HandlerExceptionResolver接口

  创建一个自定义异常类CustomException

public class CustomException extends Exception {
    private String message;

    public CustomException(String message){
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
}

  在exception 包中创建一个 HandlerExceptionResolver 接口的实现类 CustomExceptionResoler ,具体代码如下:

public class CustomExceptionResoler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ex.printStackTrace();
        CustomException ce = null;
        //如果抛出的是系统自定义异常则直接转换
        if(ex instanceof CustomException){
            ce = (CustomException) ex;
        }else {
            //如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
            ce = new CustomException("系统错误,请与系统管理员联系");
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message",ce.getMessage());
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

需要将实现类 CustomExceptionResoler 在配置文件中托管给 Spring MVC 框架才能进行异常的统一处理,配置代码为 :

<bean id="handlerExceptionResolver"
	class="com.wink.exception.CustomExceptionResoler"/>
  • 2.2 使用SimpleMappingExceptionResolver类

使用SimpleMappingExceptionResolver 类统一处理异常时,需要在配置文件中提前配置异常类和 View 的对应关系。springmvc.xml:

 <!--SimpleMappingExceptionResolver(异常类与 View 的对应关系) -->
    <bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 定义默认的异常处理页面,当该异常类型注册时使用 -->
        <property name="defaultErrorView" value="error"></property>
        <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
        <property name="exceptionAttribute" value="ex"></property>
        <!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
        <property name="exceptionMappings">
            <props>
                //如:<prop key="java.sql.SQLException">sql-error</prop>
                <!-- 在这里还可以继续扩展对不同异常类型的处理 -->
            </props>
        </property>
    </bean>
  • 2.3 使用@ExceptionHandler注解

在使用 @ExceptionHandler 注解声明统一处理异常时不需要配置任何信息。
  创建 BaseController 类,并在该类中使用 @ExceptionHandler 注解声明异常处理方法:

public class BaseController {
    @ExceptionHandler
    public String exception(HttpServletRequest request, Exception ex) {
        request.setAttribute("ex", ex);
        // 根据不同错误转向不同页面
        ......
    }
}

将所有需要异常处理的 Controller 都继承 BaseController 类:

@Controller
public class TestException extends BaseController{
    ......
}
发布了9 篇原创文章 · 获赞 1 · 访问量 251

猜你喜欢

转载自blog.csdn.net/qq_41460383/article/details/104529568
今日推荐