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