龙空技术网

【Spring系列教程七】SpringMVC常用注解

猿学堂 201

前言:

此刻各位老铁们对“springmvc跳转页面并携带数据”可能比较着重,你们都想要知道一些“springmvc跳转页面并携带数据”的相关资讯。那么小编在网上收集了一些关于“springmvc跳转页面并携带数据””的相关内容,希望我们能喜欢,同学们快快来了解一下吧!

Spring在2.5以前使用XML方式配置JavaBean,但是由于配置文件的不便以及臃肿等问题,Spring提供了@Controller、@RequestMapping、@ResponseBody等注解,不但减轻了配置,也使得开发更加的便利。在本章内将详细讲解SpringMVC中常用的注解

7.1 控制器注解7.1.1 @Controller注解

在 POJO类定义处标注@Controller,再通过<context∶component-scan/>扫描相应的类包,即可使 POJO 成为一个能处理HTTP请求的控制器。

用户可以创建数量不限的控制器,分别处理不同的业务请求,如 LoginController、UserController、ForumController 等。每个控制器可拥有多个处理请求的方法,每个方法负责不同的请求操作。如何将请求映射到对应的控制器方法中是 Spring MVC框架的重要任务之一,这项任务由@RequestMapping 承担。

在控制器的类定义及方法定义处都可以标注@RequestMapping,类定义处的@RequestMapping提供初步的请求映射信息,方法定义处的@RequestMapping 提供进一步的细分映射信息。DispatcherServlet 截获请求后,就通过控制器上@RequestMapping 提供的映射信息确定请求所对应的处理方法。

将请求映射到控制器处理方法的工作包含一系列映射规则,这些规则是根据请求中的各种信息制定的,具体包括请求URL、请求参数、请求方法、请求头这4个方面的信息项。

首先查看@Controller源码:

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Controller {    @AliasFor(annotation = Component.class)    String value() default "";}

从源码可以看出@Controller注解只有一个value属性,这个属性用于配置JavaBean在IOC容器中实例的名称,如果不配置则默认是类名首字母小写。下面的示例将演示这个注解的用法。

@Controllerpublic class IndexController {    @ResponseBody    @RequestMapping(method = RequestMethod.GET,value = "/index")    public String index(String name){        return "Hello "+name;    }}
7.1.2 @RequestMapping注解

在上一小节已经简单介绍了@RequestMapping注解,@RequestMapping的作用是将HTTP请求正确的映射到对应的类中的方法。从而让对应的方法处理请求,并给出做出响应。首先查询@RequestMapping的源码:

@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Mappingpublic @interface RequestMapping {    //给映射地址指定一个别名	String name() default "";    //用于将指定请求的地址映射到方法	@AliasFor("path")	String[] value() default {};    //同value	@AliasFor("value")	String[] path() default {};    //映射指定请求的方法,包括GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE	RequestMethod[] method() default {};	//指定request中必须包含某些参数值时,才让该方法处理请求	String[] params() default {};    //指定request中必须包含某些指定的header值,才能让该方法处理请求	String[] headers() default {};    //指定处理请求的提交内容(Content-Type),例如:application/json	String[] consumes() default {};    //指定返回的内容类型,返回的内容类型必须是request请求头中所包含的类型	String[] produces() default {};}

@RequestMapping注解支持的常用属性示例如下。

属性

类型

是否必要

说明

value

String[]

用于将指定请求的地址映射到方法

name

String

给映射地址指定一个别名

method

RequestMethod[]

映射指定请求的方法,包括GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE

consumes

String[]

指定处理请求的提交内容(Content-Type),例如:application/json

produces

String[]

指定返回的内容类型,返回的内容类型必须是request请求头中所包含的类型

params

String[]

指定request中必须包含某些参数值时,才让该方法处理请求

headers

String[]

指定request中必须包含某些指定的header值,才能让该方法处理请求

path

String[]

用于将指定请求的地址映射到方法

value属性:@RequestMapping 是一个用来处理请求地址映射的注解,可以使用 @RequestMapping 注释一个方法或类。一个采用@RequestMapping注释的方法将成为一个请求处理方法, 例如:

@RequestMapping(value = "/index") public String index(String name){     return "Hello "+name; }
method属性,该属性用来指示该方法仅处理哪些HTTP请求方式。
@RequestMapping(method = RequestMethod.GET,value = "/index")

以上代码method=RequestMethod.GET表示该方法支持GET请求。也可以同时支持多个HTTP请求方式,如:

@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST},value = "/index")

Spring 4.3 之后,新增了@GetMapping、@PostMapping、 @PutMapping、@DeleteMapping、@PatchMapping 注解,这几个注解可 以指定的属性和@RequestMapping注解类似,区别在于@GetMapping注 解只支持GET方式的请求;@PostMapping注解只支持POST方式的请求,@PutMapping@DeleteMapping、@PatchMapping分别对应PUT请 求、DELETE请求和PATCH请求,使用比较少。

consumes属性 该属性指定处理请求的提交内容类型(Content-Type)。

@RequestMapping(consumes = "application/json",value = "/index")

表示方法仅处理request Content-Type为“application/json”类型的请求。

produces属性,该属性指定返回的内容类型,返回的内容类型必须是 request 请求

头(Accept)中所包含的类型。

@RequestMapping(produces = "application/json",value = "/index")

方法仅处理request请求中Accept头中包含了"application/json"的请 求,同时指明了返回的内容类型为application/json。

params属性 该属性指定request中必须包含某些参数值时,才让该方法处理。

@RequestMapping(params = "param=value",value = "/index")

方法仅处理其中名为“param、值为“value”的请求。

@RequestMapping 不但支持标准的 URL,还支持 Ant 风格(?、*和**字符)的和带{xxx}占位符的URL。以下 URL 都是合法的。

/user/*/createUser∶ 匹配/user/aa/createUser、/user/bbb/createUser等 URL。/user/**/createUser∶匹配/user/createUser、/user/aaa/bbb/createUser 等URL。/user/createUser??∶匹配/user/createUseraa、/user/createUserbb等 URL。/user/{userld}∶匹配 user/123、user/456 等URL。/user/**/{userId}∶匹配 user/aa/bbb/123、user/aaa/456等 URL。company/{companyld}/user/{userId}/detail∶匹配 company/123/user/456/detail 等URL。7.2 请求处理方法参数

Spring MVC 对控制器处理方法签名的限制是很宽松的,用户几乎可以按自己喜欢的方式进行方法签名。在必要时对方法及方法入参标注相应的注解(如@PathVariable、@RequestParam、@RequestHeader 等)即可,Spring MVC 会优雅地完成剩下的工作∶将 HTTP请求的信息绑定到相应的方法入参中,并根据方法返回值类型做出相应的后续处理。

7.2.1 @RequestParam

在Servlet中我们知道,如果需要获取请求参数,需要使用HttpServletRequest对象的getParameter()方法,在SpringMVC中,只需要将方法参数列表中参数名称和请求参数名称保持一致,SpringMVC会自动将同名请求参数绑定到方法参数中,下面将示例这种用法:

新建页面,在页面中放置表单

<body>    <form action="${pageContext.request.contextPath}/index" method="get">        <input name="name" value="">        <input type="submit" value="提交">    </form></body>

定义Controller,并将页面提交的数据

@Controllerpublic class IndexController {    @GetMapping("/index")    public String index(String name){        System.out.println(name);        return null;    }}

需要注意的是页面中参数的name要和方法的参数名称保持一致,否则参数无法映射。如果出现页面中提交的参数名称不一致的情况,也可以使用@RequestParam注解将请求参数和方法参数进行绑定。以上例为例,假设页面中<input>标签的name属性为username,那么在controller的方法参数上可以做如下修改:

@Controllerpublic class IndexController {    @GetMapping("/index")    public String index(@RequestParam("username") String name){        System.out.println(name);        return null;    }}

查看@RequestParam注解源码:

@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RequestParam {	@AliasFor("name")	String value() default "";	@AliasFor("value")	String name() default "";	boolean required() default true;	String defaultValue() default ValueConstants.DEFAULT_NONE;}

各个属性含义如下:

属性

类型

是否必须

说明

name

String

指定请求参数绑定的名称

value

String

name属性的别名

required

boolean

指定参数是否必须绑定

defaultValue

String

如果没有传递参数则使用默认值

在@RequestParam注解的属性中需要特别注意的是required属性,该属性指参数是否必须绑定,默认是true,也就是说如果不绑定参数值,即没有向服务端传递对应的参数,程序将抛出异常。

7.3.2 多个请求参数的绑定

在上一小节的示例中可以知道通过请求参数和方法参数的绑定,如果请求参数较少的情况下可以使用这种方式,但是如果请求参数较多的情况下这种方式显得不那么方便,此时,可以将请求参数封装到VO类中,例如登录时,通常需要填写用户名和密码,此时就可以将用户名和密码封装到一个VO中,需要注意的是,请求参数的名称必须要和VO对象的实例变量名称相同如下例所示:

<body>    <form action="${pageContext.request.contextPath}/login" method="get">        <input name="username" value=""></br>        <input name="password" value=""></br>        <input type="submit" value="提交">    </form></body>
@Controllerpublic class LoginController {    @PostMapping("/login")    public String login(UserVO userVO){        System.out.println(userVO.getUsername());        System.out.println(userVO.getPassword());        return "success.jsp";    }}

这种方式不但简化了请求参数的接收,也方便数据合法性的验证,关于数据验证的内容将会在下一章节进行讲解。

7.3 视图解析器

请求处理方法执行完成后,最终返回一个ModelAndView对象。对于那些返回String、View 或 ModelMap 等类型的处理方法,Spring MVC 也会在内部将它们装配成一个ModelAndView 对象,该对象包含了视图逻辑名和模型对象的信息。Spring MVC借助视图解析器(ViewResolver)得到最终的视图对象(View),这可能是我们常见的 JSP 视图,也可能是一个基于FreeMarker、Velocity 模板技术的视图,还可能是PDF、Excel、XML、JSON 等各种形式的视图。

视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。视图对象可以是常见的 JSP,还可以是 Excel或PDF 等形式不一的媒体形式。为了实现视图模型和具体实现技术的解耦,Spring在 org.springframework.web.servlet 包中定义了一个高度抽象的 View接口,该接口中定义了两个方法。String getContentType()∶视图对应的 MIME类型,如 text/html、image/jpeg 等。void render(Map model,HttpServletRequest request,HttpServletResponse response)∶将模型数据以某种MIME 类型渲染出来。视图对象是一个 Bean,通常情况下,视图对象由视图解析器负责实例化。由于视图 Bean是无状态的,所以它们不会有线程安全的问题。

不同类型的视图实现技术对应不同的View实现类,这些视图实现类都位于org.springframework.web.servlet.view包中,常见的View如下:

视图类型

说明

InternalResourceView

将JSP或其他资源封装成一个视图,这

InternalResourceViewResolver默认使用的视图实现类

JstlView

如果JSP文件中使用了JSTL国际化标签的功能,则需要使用该视图

FreeMakerView

使用FreeMaker模板引擎的视图

MappingJackson2JsonView

将模型数据通过Jackson开源框架的ObjectMapper以JSON方式输出

7.3.1 返回视图

在web开发中通常处理完一个请求后,需要跳转到某个页面或者Controller,本小节将会详细介绍如何返回视图。

7.3.1.1 利用方法返回值

在SpringMVC中通过控制器内的方法来接受请求并处理请求,在定义方法时,可以将方法返回值定义成String类型,当处理请求后,直接返回视图的名称,SpringMVC会自动寻找返回值对应的视图,并进行跳转

@GetMapping(value = "/studentList") public String findAll(){    return "studentList.jsp"; }
7.3.1.2 使用View

在上面的内容中讲解了集中常见的View类型,如果使用View跳转页面时,可以将方法的返回值定义为View类型,在方法中创建View子类对象,从而进行视图的返回

@GetMapping(value = "/studentList")public View findAll(){    JstlView jstlView  = new JstlView();    jstlView.setUrl("studentList.jsp");    return jstlView;}

在实际开发中,有时候不但需要跳转页面还需要把从数据库获取的数据传递到页面。很明显此时仅仅返回String或者View是不能满足需要的。那么如何解决这个问题呢?

针对这个问题,可以在方法参数中传入Model对象,Model对象用于将数据发送到视图,因为SpringMVC跳转视图默认使用请求转发方式,因此Model通常将数据封装进request对象。当页面跳转是,会自动将数据发送到视图。Model通过如下方法添加数据:

Model addAttribute(String attributeName, @Nullable Object attributeValue);

下面的实例将演示如何使用Model传递数据:

@GetMapping(value = "/studentList")public String findAll(Model model){    List<Student> list = studentService.findAll();    model.addAttribute("list",list);    return "studentList.jsp";}
7.3.1.3 使用ModelAndView

控制器处理方法的返回值如果是ModelAndView,则其既包含模型 数据信息,也包含视图信息,这样Spring MVC将使用包含的视图对模型 数据进行渲染。可以简单地将模型数据看成一个Map<String,Object>

对象。在处理方法中可以使用ModelAndView对象的如下方法添加模型数据:

addObject(String attributeName,Object attributeValue);

可以通过如下方法设置视图:

setViewName(String viewName);

下面示例ModelAndView的区别

    @GetMapping(value = "/studentList")    public ModelAndView findAll(){        List<Student> list = studentService.findAll();        ModelAndView modelAndView = new ModelAndView();        //封装视图        modelAndView.setViewName("studentList.jsp");        //封装数据        modelAndView.addObject("list",list);        return modelAndView;    }
7.3.1.5视图解析

在web开发中,通常会将页面放置在WEB-INF目录下,如果在JSP/Servlet项目中,可以利用过滤器对请求进行转发,在SpringMVC中可以以如下方式配置:

<bean id="internalResourceView" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/"/>        <property name="suffix" value=".jsp"/></bean>

其中prefix配置了页面跳转的前缀路径,而suffix通常配置视图的扩展名,这样在跳转视图时,只需要写视图名称即可。例如跳转到/WEB-INF/success.jsp时,只需要填写视图名称success。

7.3.2 静态资源处理

在使用SpringMVC开发应用时,因为所有的请求都交由了DispatcherServlet处理,而DispatcherServlet并不会对静态资源进行处理,这就需要手动配置静态资源的位置。

<mvc∶resources/允许静态资源放置在任何地方,如 WEB-INF 目录下、类路径下等,甚至可以将 JavaScript 等静态文件打包到JAR 包中。通过location 属性指定静态资源的位置,由于location 属性是Resource类型,因此可以使用诸如"classpath∶"等的资源前缀指定资源位置。传统 Web 容器的静态资源只能放在 Web 容器的根路径下,<mvc∶resources/>则完全打破了这个限制。

在接收到静态资源的获取请求时,会检查请求头的Last-Modified值。如果静态资源没有发生变化,则直接返回 303响应状态码,指示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端,以充分节省带宽,提高程序性能。

在SpringMVC配置文件中进行如下配置:

<mvc:resources mapping="/static/**" location="/WEB-INF/static"></mvc:resources>

其中mapping属性配置的是访问静态资源时的路径,而location属性则是指静态资源实际存放的位置。

7.4 @SessionAttribute和@CookieValue

@SessionAttribute注解允许我们有选择地指定Model中的哪些属性转存到 HttpSession对象当中。 该注解源码如下:

@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface SessionAttribute {	/**	 * 指定请求参数绑定的名称	 */	@AliasFor("name")	String value() default "";	/**	 * 同name	 */	@AliasFor("value")	String name() default "";	/**	 * 指定参数是否必须绑定	 */	boolean required() default true;}

示例代码如下:

@RequestMapping(value="/arrtibuteTest")public void arrtibuteTest (@SessionAttribute(value="username")String username){   }

以上代码会自动将session作用域中名为username的属性的值设置到username参数上。 @CookieValue的作用和@SessionAttribute的作用类似,只是作用域由Session变成了Cookie。

标签: #springmvc跳转页面并携带数据