springMvc注解@ControllerAdvice,@InitBinder,@CrossOrigin,@CookieValue

本文详细介绍了 Spring MVC 中的关键注解,包括 @ControllerAdvice 的作用和配置方式,以及 @ExceptionHandler、@InitBinder 和 @ModelAttribute 的具体用法。此外还探讨了如何通过 @InitBinder 解决数据绑定的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@ControllerAdvice  spring3.2提供的新注解,作用:控制器增强

/**
 * Indicates the annotated class assists a "Controller".
 *
 * <p>Serves as a specialization of {@link Component @Component}, allowing for
 * implementation classes to be autodetected through classpath scanning.
 *
 * <p>It is typically used to define {@link ExceptionHandler @ExceptionHandler},
 * {@link InitBinder @InitBinder}, and {@link ModelAttribute @ModelAttribute}
 * methods that apply to all {@link RequestMapping @RequestMapping} methods.
 *
 * <p>One of {@link #annotations()}, {@link #basePackageClasses()},
 * {@link #basePackages()} or its alias {@link #value()}
 * may be specified to define specific subsets of Controllers
 * to assist. When multiple selectors are applied, OR logic is applied -
 * meaning selected Controllers should match at least one selector.
 *
 * <p>The default behavior (i.e. if used without any selector),
 * the {@code @ControllerAdvice} annotated class will
 * assist all known Controllers.
 *
 * <p>Note that those checks are done at runtime, so adding many attributes and using
 * multiple strategies may have negative impacts (complexity, performance).
 *
 * @author Rossen Stoyanchev
 * @author Brian Clozel
 * @author Sam Brannen
 * @since 3.2
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {

	/**
	 * Alias for the {@link #basePackages} attribute.
	 * <p>Allows for more concise annotation declarations e.g.:
	 * {@code @ControllerAdvice("org.my.pkg")} is equivalent to
	 * {@code @ControllerAdvice(basePackages="org.my.pkg")}.
	 * @since 4.0
	 * @see #basePackages()
	 */
	@AliasFor("basePackages")
	String[] value() default {};

	/**
	 * Array of base packages.
	 * <p>Controllers that belong to those base packages or sub-packages thereof
	 * will be included, e.g.: {@code @ControllerAdvice(basePackages="org.my.pkg")}
	 * or {@code @ControllerAdvice(basePackages={"org.my.pkg", "org.my.other.pkg"})}.
	 * <p>{@link #value} is an alias for this attribute, simply allowing for
	 * more concise use of the annotation.
	 * <p>Also consider using {@link #basePackageClasses()} as a type-safe
	 * alternative to String-based package names.
	 * @since 4.0
	 */
	@AliasFor("value")
	String[] basePackages() default {};

	/**
	 * Type-safe alternative to {@link #value()} for specifying the packages
	 * to select Controllers to be assisted by the {@code @ControllerAdvice}
	 * annotated class.
	 * <p>Consider creating a special no-op marker class or interface in each package
	 * that serves no purpose other than being referenced by this attribute.
	 * @since 4.0
	 */
	Class<?>[] basePackageClasses() default {};

	/**
	 * Array of classes.
	 * <p>Controllers that are assignable to at least one of the given types
	 * will be assisted by the {@code @ControllerAdvice} annotated class.
	 * @since 4.0
	 */
	Class<?>[] assignableTypes() default {};

	/**
	 * Array of annotations.
	 * <p>Controllers that are annotated with this/one of those annotation(s)
	 * will be assisted by the {@code @ControllerAdvice} annotated class.
	 * <p>Consider creating a special annotation or use a predefined one,
	 * like {@link RestController @RestController}.
	 * @since 4.0
	 */
	Class<? extends Annotation>[] annotations() default {};

}
在@ControllerAdvice注解类的内部使用@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法
@ControllerAdvice  
public class ControllerAdviceTest {  
  
    @ModelAttribute  
    public User newUser() {  
        System.out.println("============应用到所有@RequestMapping注解方法,在其执行之前把返回值放入Model");  
        return new User();  
    }  
  
    @InitBinder  
    public void initBinder(WebDataBinder binder) {  
        System.out.println("============应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器");  
    }  
  
    @ExceptionHandler(UnauthenticatedException.class)  
    @ResponseStatus(HttpStatus.UNAUTHORIZED)  
    public String processUnauthenticatedException(NativeWebRequest request, UnauthenticatedException e) {  
        System.out.println("===========应用到所有@RequestMapping注解的方法,在其抛出UnauthenticatedException异常时执行");  
        return "viewName"; //返回一个逻辑视图名  
    }  
}  

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
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 {};

}
@ExceptionHandler({UnauthorizedException.class, UnknownAccountException.class, UnauthenticatedException.class, AuthenticationException.class})
    public String processShiroExceptions() {
        return "403";
    }

  @InitBinder标识的方法,可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定。
• @InitBinder方法不能有返回值,它必须声明为void。
• @InitBinder方法的参数通常是是 WebDataBinder。

@InitBinder  
    public void initBinder(WebDataBinder binder){  
        //TODO
    }  
http://blog.youkuaiyun.com/axin66ok/article/details/17938095

在SpringMVC中,bean中定义了Date,double等类型,如果没有做任何处理的话,日期以及double都无法绑定。
解决的办法就是使用spring mvc提供的@InitBinder标签,可以在BaseController中增加方法initBinder,并使用注解@InitBinder标注,那么spring mvc在绑定表单之前,都会先注册这些编辑器,当然你如果不嫌麻烦,你也可以单独的写在你的每一个controller中。剩下的控制器都继承该类。spring自己提供了大量的实现类,诸如CustomDateEditor ,CustomBooleanEditor,CustomNumberEditor等许多,基本上够用。

@InitBinder    
   protected void initBinder(WebDataBinder binder) {    
       binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));    
/        binder.registerCustomEditor(int.class, new CustomNumberEditor(int.class, true));    
       binder.registerCustomEditor(int.class, new IntegerEditor());    
/        binder.registerCustomEditor(long.class, new CustomNumberEditor(long.class, true));  
       binder.registerCustomEditor(long.class, new LongEditor());    
       binder.registerCustomEditor(double.class, new DoubleEditor());    
       binder.registerCustomEditor(float.class, new FloatEditor());    
   }   
@InitBinder
    protected void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        binder.registerCustomEditor(Timestamp.class, new CustomDateEditor(dateFormat, true));
    }

@CrossOrigin用来处理跨域请求

@CookieValue 可让处理方法入参绑定某个 Cookie 值

@RequestMapping("/springmvc")  
@Controller  
public class HelloWorld {  
@RequestMapping("/testCookieValue")  
    public String testCookieValue(@CookieValue("JSESSIONID")String sessionId){  
        System.out.println("testCookieValue: "+sessionId);  
        return "success";  
    }  
}  

@ModelAttribute 被此注解注解的方法会在此controller每个方法执行前被执行,因此对于一个controller映射多个URL的用法来说,要谨慎使用

@RequestMapping("index1")
    @ResponseBody
    public Object inde1x(Model model){

        return "sss";
    }

    @ModelAttribute//abc这个
    public void populateModel(@RequestParam String abc, Model model) {
        model.addAttribute("attributeName", abc);
    }
@RequestMapping("index1")
    @ResponseBody
    public Object inde1x(@ModelAttribute("userPojo") UserPojo userPojo){

        return "sss";
    }

    @ModelAttribute("userPojo")
    //UserPojo这个类
    public UserPojo addPojo(@RequestParam String userName) {
        return new UserPojo(userName);
    }

@ModelAttribute("attributeName")
    public String addAccount(@RequestParam String abc) {
        //在model中增加key=attributeName,value=abc(由浏览器传过来而定)的键值对
        return abc;
    }

@RequestMapping(value = "/helloWorld")
    @ModelAttribute("attributeName")
    public String helloWorld() {
        //这时这个方法的返回值并不是表示一个视图名称,而是model属性的值(key=attributeName,value=hi),视图名称由RequestToViewNameTranslator根据请求"/helloWorld"转换为逻辑视图helloWorld。
        return "hi";
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值