SpringMVC中的常用注解源码及解析
用于配置控制器的注解
@Controller
该注解用用于修饰表现层控制器的注解
源码
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { // 用于指定存入IOC容器是Bean的唯一标识 @AliasFor(annotation = Component.class) String value() default ""; }
@RestController
该注解具备@Controller注解的全部功能,同时多了一个@ResponseBody注解的功能
源码
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController { // 用于指定存入ioc容器时bean的唯一标识。 @since 4.0.1 @AliasFor(annotation = Controller.class) String value() default ""; }
用于提供方法映射的注解
@RequestMapping
该注解用于建立请求URL和处理请求方法之间的对应关系
注解在类上: 请求URL的第一级访问目录. 如果没有的话, 就相当于从应用根目录开始. 放在类上的目的就是为了将URL可以按照模块化管理.
源码以及解析
package org.springframework.web.bind.annotation; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface RequestMapping { // 给当前url 提供一个名称 String name() default ""; // value: 用于指定请求的URL . 和path属性作用一样 // 注意: 该属性的值 前边加不加 "/" 都是一样的. @AliasFor("path") String[] value() default {}; // 4.2 版本中加入的注解 和value属性一样 // @since 4.2 @AliasFor("value") String[] path() default {}; // method:用于指定请求的方式。它支持以下这些类型: // GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE. // 是通过RequestMethod枚举指定的 RequestMethod[] method() default {}; // params:用于指定限制请求参数的条件。它支持简单的表达式。 // 要求请求参数的key和value必须和配置的一模一样。 // 示例: params = {"accountName"},表示请求参数必须有accountName // params = {"moeny!100"},表示请求参数中money不能是100。 String[] params() default {}; // headers:用于指定限制请求消息头的条件。 // 示例: RequestMapping(value = "/something", headers = "content-type=text/*") String[] headers() default {}; // consumes:用于指定可以接收的请求正文类型(MIME类型) // 示例: consumes = "text/plain" , consumes = {"text/plain", "application/*"} String[] consumes() default {}; // produces:用于指定可以生成的响应正文类型。(MIME类型) // produces = "text/plain" // produces = {"text/plain", "application/*"} // produces = MediaType.APPLICATION_JSON_UTF8_VALUE String[] produces() default {}; }
@GetMapping 、@PostMapping、 @PutMapping 、@DeleteMapping 、是@RequestMapping 注解的衍生注解
除了method指定以外 , 其他和@RequestMapping 相同
可以看下源码@PostMapping示例
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @RequestMapping( method = {RequestMethod.POST} ) public @interface PostMapping {
增强控制器方法的注解
@ModelAttribute
它可以用于修饰方法,或者是参数。
- 当修饰方法时,表示执行控制器方法之前,被此注解修饰的方法都会执行。
- 当修饰参数时,用于获取指定的数据给参数赋值。
@Controller public class ModelAttributeController { @ModelAttribute("username") public String showModel(String username){ System.out.println("showModel method name is "+username); username = username + "aaa"; return username; } @RequestMapping("/useModelAttribute") public String useModelAttribute(@ModelAttribute("username") String username){ System.out.println("controller method name is "+username); return "success"; } }
测试结果
showModel method name is test
controller method name is testaaa
success.jsp执行了
@ExceptionHandler
用于注释方法,表明当前方法是控制器执行产生异常后的处理方法.
示例:
自定义异常
package com.exception; /** * 自定义异常(处理业务异常) */ public class CustomerException extends Exception{ private String message; public CustomerException(String message){ this.message = message; } @Override public String getMessage() { return message; } }
异常后处理类
@ControllerAdvice public class ExceptionHandlerAdvice { @ExceptionHandler(Exception.class) public String handleException(Model model, Exception e){ String errorMsg = ""; //判断Exception的类型是不是CustomerException if(e instanceof CustomerException){ errorMsg = e.getMessage(); }else { //系统异常 errorMsg = "服务器内部错误,请联系管理员!"; } model.addAttribute("errorMsg",errorMsg); return "error"; } }
接口控制器类
package com.web.controller; @ControllerAdvice public class ExceptionHandlerAdvice { @ExceptionHandler(Exception.class) public String handleException(Model model, Exception e){ String errorMsg = ""; //判断Exception的类型是不是CustomerException if(e instanceof CustomerException){ errorMsg = e.getMessage(); }else { //系统异常 errorMsg = "服务器内部错误,请联系管理员!"; } model.addAttribute("errorMsg",errorMsg); return "error"; } }
测试
<%-- ExceptionHandler注解的使用--%> <a href="useExceptionHandler?age=111" rel="external nofollow" >ExcpetionHandler注解的使用</a> <hr/>
@InitBinder
用于初始化表单请求参数的数据绑定器。
给控制器方法提供通知的注解
@ControllerAdive
用于给控制器提供一个增强的通知。
@RestControllerAdive
它和@ControllerAdvice注解的作用一样,并且支持@ResponseBody的功能
用于绑定控制器方法参数的注解
@RequestParam
此注解是从请求正文中获取请求参数,给控制器方法形参赋值的 当请求参数的名称和控制器方法形参变量名称一致时,无须使用此注解。 当没有获取到请求参数时,此注解还可以给控制器方法形参提供默认值。 只能用在方法的参数上.
示例:
@RequestMapping("/useRequestParam") public String useRequestParam(@RequestParam(value = "page",defaultValue = "10") int page){ System.out.println("当前页是:"+page); return "success"; }
@RequestBody
该注解用于读取 Request 请求的 body 部分数据,使用系统默认配置的 HttpMessageConverter 进行解析,然后把相应的数据绑定到要返回的对象上; 再把 HttpMessageConverter 返回的对象数据绑定到 controller 中方法的参数上。
也就是说,如果是 json 格式的数据,我们要传入的参数是一个对象,那就必须使用 @RequestBody
。
示例:
@RequestMapping("/useRequestBody") public String useRequestBody(@RequestBody(required = false) User user){ //System.out.println("不支持跨域 user is "+user); System.out.println(" user is "+user); return "success"; }
测试页面
<a href="#" rel="external nofollow" id="useRequestBodyAjax">RequestBody注解的使用</a> <%-- RequestBody注解的使用--%> <script src="js/jquery-2.2.3.min.js"></script> <%-- <script src="${pageContext.request.contextPath}/js/jquery-2.2.3.min.js"></script>--%> <script type="text/javascript"> //页面加载事件 $(function () { //给Id为useRequestBodyAjax超链接绑定一个点击事件 $("#useRequestBodyAjax").click(function () { alert("点击事件绑定成功"); $.ajax({ url: "useRequestBody", type: "post", // data:"username=test&age=18&gender=male", data: '{"username":"test","age":25,"gender":"male"}',//json contentType: "application/json", dataType: "text", success: function (data) { alert(data); } }); }); }) </script>
@RequestHeader
该注解是从请求消息头中获取消息头的值,并把值赋给控制器方法形参。
注意: 它只能出现在方法的参数上
@RequestMapping("/useRequestHeader") public String useRequestHeader (@RequestHeader(value = "Accept-Language",required = false,defaultValue = "test") String header) { System.out.println("Accept-Language:"+header); return "success"; }
@CookieValue
从请求消息头中获取Cookie的值,并把值赋给控制器方法形参。
属性:
- name = value cookie的key名称
- required boolean 是否必须
- defaultValue 默认值
@CookieValue(value = "JSESSIONID" , required = true, defaultValue = "")
示例:
@RequestMapping("/useCookieValue") public String useCookieValue(@CookieValue("JSESSIONID") String jsessionid){ System.out.println(jsessionid); return "success"; }
@PathVariable
restful 该注解是springmvc框架支持rest风格url的标识。用于获取请求url映射中占位符对应的值。
示例
@RequestMapping(method = RequestMethod.PUT,value = "/{id}") public String update(@PathVariable Integer id, User user){ //1.给user的id赋值 user.setId(id); //2.输出 System.out.println("user is "+user); return "success"; }
改变响应方式的注解
@SessionAttributes
- 通过此注解即可实现把数据存入会话域,而无需在使用HttpSession的setAttribute方法。
- 当在控制器方法形参中加入Model或者ModelMap类型参数时,默认是存入请求域的。
- 但当控制器上使用了此注解,就会往会话域中添加数据。
package com.web.controller; /** * SessionAttribute和SessionAttributes注解的使用 */ @Controller @SessionAttributes(value = {"message"}) public class SessionAttributesController { /** * 往session域中存入数据 * 在没有SessionAttributes注解时,当控制器方法的参数有Model,ModelMap时是默认往请求域中存入数据 * @return */ @RequestMapping("/useSessionAttributes") public String useSessionAttributes(Model model){ model.addAttribute("message","存入请求域的数据"); return "success"; } @RequestMapping("/useSessionAttribute") public String useSessionAttribute(HttpServletRequest request,@SessionAttribute(value = "message",required = false) String message){ System.out.println(message); System.out.println("request attribute "+request.getAttribute("message")); return "success"; } }
@SessionAttributes 往会话域中存数据
@SessionAttribute 从会话域中取数据
@ResponeBody
用于用流输出响应正文
将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。
- 当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。
- 如果返回值是字符串,那么直接将字符串写到客户端;
- 如果是一个对象,会将对象转化为json串,然后写到客户端。
@RequestMapping("/useResponseBody") public String useResponseBody(){ return "use response body"; }
提供跨域访问
@CrossOrigin
跨域访问
当一个域名请求另一个域名的资源时, 就是跨域 (协议,主机名, 端口任何一个不相同就是跨域)
域名模拟 C:/Windows/System32/drivers/ect/hosts(文件)
修改该文件,建立Ip和域名的对应关系
如何刷新域名不重启计算机
cmd命令行输入:
ipconfig /displaydns
ipconfig /flushdns
跨域请求中,请求时可以正常发出去,并且服务端也可以收到. 问题出在了响应身上,通过修改服务端的响应头就可以解决跨域问题.
解决跨域问题,不使用@CrossOrigin注解的解决办法-添加跨域过滤器
package com.filters; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CrossOriginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { try{ HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse)res; System.out.println("解决跨域问题的过滤器执行了"); //设置response的响应消息头实现跨域问题的解决 /* 允许跨域的主机地址 */ response.setHeader("Access-Control-Allow-Origin", "*"); /* 允许跨域的请求方法GET, POST, HEAD 等 */ response.setHeader("Access-Control-Allow-Methods", "*"); /* 重新预检验跨域的缓存时间 (s) */ response.setHeader("Access-Control-Max-Age", "3600"); /* 允许跨域的请求头 */ response.setHeader("Access-Control-Allow-Headers", "*"); /* 是否携带cookie */ response.setHeader("Access-Control-Allow-Credentials", "true"); //放行 chain.doFilter(request,response); }catch (Exception e){ e.printStackTrace(); } } @Override public void destroy() { } }
在spring中提供了@CrossOrigin注解来解决跨域问题,
该注解可以放在类上和方法上, 以解决跨域问题.
/** * 跨域访问的方法 * @param user * @return */ @RequestMapping("/useCrossOrigin") @ResponseBody @CrossOrigin public String useCrossOrigin(@RequestBody(required = false) User user){ System.out.println("user is "+user); return "success"; }
写在类上表示该类中的所有资源都允许跨域访问, 写在方法上表示仅该方法允许跨域访问.
注意: 一些静态资源 例如 img 中的 src , link 中的 href 中的是可以进行跨域访问的
比如在 一个jsp页面中 , 如果使用 response.sendRedirect(); 会有跨域问题, 改为 window.location.href = ‘//xxx.xxx.xxx’ 则不会有跨域问题 . (踏平的坑!)
到此这篇关于SpringMVC中的常用注解源码及解析的文章就介绍到这了,更多相关SpringMVC中的常用注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解使用Spring Cloud Consul实现服务的注册和发现
这篇文章主要介绍了详解使用Spring Cloud Consul实现服务的注册和发现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-06-06
最新评论