SpringMVC-03

SpringMVC

1.在SpringMVC中使用Session

当需要向Session中存入数据时,可以使用【ModelMap】对象将数据进行封装,操作方式与封装转发的数据完全相同,例如:

modelMap.addAttribute("username", username);

然后,需要在当前控制器类之前添加@SessionAttributes注解,并且,在注解中显式的指定ModelMap中封装的哪些数据是需要存储在Session中的,例如:

@Controller 
@RequestMapping(value="user")
@SessionAttributes("username")
public class UserController {
    // ...
}

当添加了以上注解后,如果【ModelMap中被存入了名为【username的数据,该数据就在Session中,而【ModelMap中的其它数据依然只能用于转发,也就是数据的作用域只在【Request】级别。

关于【@SessionAttributes注解,其属性的配置可以参考该注解的源代码:

@AliasFor("names")
String[] value() default {};

@AliasFor("value")
String[] names() default {};

Class<?>[] types() default {};

通过以上源代码可以看到:【value和【names属性的作用是完全相同,用于指定【ModelMap中的哪些名称对应的数据需要存放到【Session】中,可以使用字符串数组表示多个属性,另外,还可以配置【types属性用于指定【Session】的数据的数据类型,也可以是数组类型,与配置的【names保持一致即可。

使用这种做法操作Session非常简单,但是,也存在一系列的问题:
      1.默认情况下,重定向时会把Session中的数据暴露在URL中;
      2.通过ModelMap存放的数据一定会在Request的作用域中,所以,通过这种方式存放到Session中的数据,其实在Request中也是存在的;
      3.通过这种方式存放到Session中的数据,不可以通过Session对象的【invalidate()方法清除!只能通过SessionStatus类的【setComplete()方法进行清除!

更加简单的操作Session的方式就是直接在处理请求的方法中添加【HttpSession类型的参数,在方法体中直接操作即可。

@RequestMapping("handle_login.do") 
public String handleLogin(String username, String password,
        ModelMap modelMap, HttpSession session) {
    // 日志
    System.out.println("UserController.handleLogin()");
    System.out.println("\tusername=" + username);
    System.out.println("\tpassword=" + password);

    // 判断用户名是否正确
    if ("root".equals(username)) {
        // 是:判断密码是否正确
        if ("1234".equals(password)) {
            // 是:登录成功,将用户名存入到Session
            // modelMap.addAttribute("username", username);
            session.setAttribute("username", username);
            // 重定向到主页
            return "redirect:../index.do";
        } else {
            // 否:密码错误
            modelMap.addAttribute("errorMessage", "ModelMap:密码错误");
            return "error";
        }
    } else {
        // 否:用户名错误
        modelMap.addAttribute("errorMessage", "ModelMap:用户名错误");
        return "error";
    }
}

使用这种做法并不存在以上使用@SessionAttributes时的各种问题,操作也非常简单,缺点就是不易于执行单元测试!

但有时可以忽略这个缺点,甚至“不使用@SessionAttributes”,原因可能是:可以使用专门的测试工具去测试控制器,所以,在控制器中的方法本身是不需要执行单元测试的,甚至在大型项目中根本就不会使用Session,那各种使用方式都是不需要的!

2.在SpringMVC中统一处理异常

   在Java中,异常的继承体系是:

Throwable
    Error
        OutOfMemoryError
    Exception
        SQLException
        IOEException
            FileNotFoundException
        RuntimeException
            NullPointException
            ClassNotFoundException
            AirthmeticException
            NumberFormatException
            IndexOutOfBoundsException
                ArrayIndexOutOfBoundsException
                StringIndexOutOfBoundsException

       常见异常处理的做法为捕获【try...catch】或者声明抛出【throw/throws】,在实际处理时,如果当前类适合处理该异常,则捕获,如果不适合,则声明并向上层抛出,由上层调用者决定是否处理该异常,通常适合处理异常的都是【控制器】,但是异常可能在多个功能中都会出现,在处理不同的请求时,采用相同代码处理,则会造成代码冗余,不便于统一管理,所以在SpringMVC框架中提供了统一处理异常的机制。
       可以在控制器类中添加统一处理异常的方法,关于该方法:
1.使用【public】权限;
2.返回值的意义与处理请求的方法完全相同;
3.方法名称可以自定义;
4.方法中必须包含异常类型的参数,且参数的类型能包括所有可能需要处理的异常;
5.与处理请求的方法不同,不可以使用【ModelMap】等对象,只能添加【HttpServletRequest】参数;
6.必须添加【@ExceptionHandler】注解,所以,处理i请求的方法可以是:

@ExceptionHandler
public String handleException(Throwable ex, HttpServletRequest request) {
    if (ex instanceof NullPointerException) {
        request.setAttribute("errorMessage", "空指针异常!");
    } else if (ex instanceof ArrayIndexOutOfBoundsException) {
        request.setAttribute("errorMessage", "数据下标越界异常异常!");
    } else {
        request.setAttribute("errorMessage", "未知异常:" + ex.getClass().getName());
    }
    return "error";
}

       一旦添加了该方法,当前类中任何处理请求的方法都不需要处理相关异常,等同于这些方法把异常抛出了,所有抛出的异常将由该方法统一处理,需要注意的是,该方法只能处理该控制器出现的异常,其他控制器类抛出的异常不做处理。所以可以把该处理异常的方法放在所有控制器类公共的父类中,如【BaseController】!

关于@ExceptionHandler的源代码:

public @interface ExceptionHandler {

    /**
     * Exceptions handled by the annotated method. If empty, will default to any
     * exceptions listed in the method argument list.
     */
    Class<? extends Throwable>[] value() default {};

}

       该注解可以指定需要被处理的异常的种类,允许定义多个异常处理方法,单独处理同一类型异常,其参数可以是数组,即同时指定多种异常都将被该方法进行处理!

SpringMVC重点内容:

  1. 理解SpringMVC执行核心流程;
  2. 掌握获取请求参数的方式;
  3. 理解转发与重定向;
  4. 了解转发时如何转发数据;
  5. 掌握@RequestMapping、@RequestParam注解的使用;
  6. 掌握拦截器的使用;
  7. 掌握处理异常的使用。
发布了29 篇原创文章 · 获赞 6 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览