Spring MVC 使用介绍(五)—— 注解式控制器(一):基本介绍
一、hello world
相对于基于Controller接口的方式,基于注解方式的配置步骤如下:
- HandlerMapping 与HandlerAdapter 分别配置为RequestMappingHandlerMapping、RequestMappingHandlerAdapter(或者添加配置:<mvc:annotation-driven />,详见:<mvc:annotation-driven/>的作用)
- 定义Controller类,添加注解@Controller
- 实例化为bean(xml中显示配置为bean,或添加配置:<context:component-scan />)
控制器
@Controller //@RequestMapping(value = "/matt") public class TestController { @RequestMapping(value = "/hello") public ModelAndView helloWorld() { ModelAndView mv = new ModelAndView(); mv.addObject("message", "hello world"); mv.setViewName("hello"); return mv; } }
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <!-- HandlerMapping --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean> <!-- HandlerAdapter --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> <!-- ViewResolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean class="cn.matt.controller.TestController"/> </beans>
hello.jsp
<%@ page language="java" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> ${message} </body> </html>
启动后,访问http://localhost:8080/myweb/hello
二、处理器映射:@RequestMapping
@RequestMapping可使用在方法和类上
- 方法:表示处理器映射,如上例
- 类:表示窄化请求映射,如上例控制器类上添加@RequestMapping(value = "/matt"),访问路径变为:http://localhost:8080/myweb/matt/hello
三、处理器返回值类型
处理器返回值类型可以为以下几种:
- ModelAndView:通过该对象,可分别对Model及View进行设置
- String:返回视图名,或对页面进行转发和重定向,可通过处理方法的Model参数添加数据
- "视图名":即表示视图,真实的访问路径为:“前缀”+"视图名"+“后缀”
- “redirect:path”:重定向,和response.sendRedirect()类似,但不同的是
- "/"表示当前上下文,而非全局上下文,与请求转发相同
- 在url中会添加当前Model的设置的key-value值
- "forward:path":请求转发,与request.getRequestDispatcher(..).forward(..)相同
- void:通过HttpServletRequest、HttpServletResponse进行请求的转发、重定向,或结果的直接输出
测试示例
@Controller public class TestController3 { // 1、ModelAndView @RequestMapping(value = "/return1") public ModelAndView testReturnValue1() { ModelAndView mv = new ModelAndView(); mv.addObject("message", "hello world"); mv.setViewName("hello"); return mv; } // 2、String: 视图名 @RequestMapping(value = "/return2") public String testReturnValue2(Model model) { model.addAttribute("message", "yeah!!"); return "hello"; } // 2、String: 重定向 @RequestMapping(value = "/return3") public String testReturnValue3(Model model) { model.addAttribute("name", "matt"); model.addAttribute("message", "oh my god"); return "redirect:/return2"; } // 2、String: 请求转发 @RequestMapping(value = "/return4") public String testReturnValue4(Model model) { model.addAttribute("name", "matt"); model.addAttribute("message", "oh my god"); return "forward:/return2"; } // 3、void @RequestMapping(value = "/return5") public void testReturnValue5(HttpServletRequest request, HttpServletResponse response) throws Exception { // 页面转发 // request.getRequestDispatcher("/return2").forward(request, response); // 页面重定向 // response.sendRedirect("/myweb/return2"); // response直接输出结果 response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串"); } @RequestMapping("/model1") public String testModel1(@ModelAttribute("user") UserInfo userInfo) { return "hello"; } }
hello.jsp
<%@ page language="java" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> ${message} ${name} </body> </html>
测试结果
输入:http://localhost:8080/myweb/return1 输出:hello world 输入:http://localhost:8080/myweb/return2 输出:yeah!! 输入:http://localhost:8080/myweb/return3 重定向到:http://localhost:8080/myweb/return2?name=matt&message=oh+my+god 输出:yeah!! 输入:http://localhost:8080/myweb/return4 输出:yeah!! matt 输入:http://localhost:8080/myweb/return5 输出:json串
关于web中相对路径的使用,详细说明可参考javaweb学习总结(八)——HttpServletResponse对象(二) 第三小节
四、JSON输出:@ResponseBody与@RestController
1、@ResponseBody基本使用
@ResponseBody用于将方法返回的对象输出为JSON数据,除在方法上添加该注解外,还需要:
i)添加转化器配置(对象 -> JSON)
ii)添加Jackson依赖
使用示例如下:
控制器
@Controller //@ResponseBody public class TestController { @RequestMapping(value = "/hello") @ResponseBody public Map<String, Object> helloWorld() { Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "matt"); map.put("age", 29); return map; } @RequestMapping(value = "/hello2") @ResponseBody public String helloWorld2() { return "选择比努力更重要!"; } }
除HandlerAdapter,spring-mvc.xml的其他配置与上例相同
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> </list> </property> </bean>
添加依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.4.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.3</version> </dependency>
启动后,访问http://localhost:8080/myweb/hello,输出:{"age":29,"name":"matt"}
补充:当使用配置<mvc:annotation-driven />时,转化器的配置方式如下:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
关于json转化器的详细介绍和中文乱码问题,可参考Spring Mvc @ResponseBody String返回中文字符串乱码
2、@ResponseBody的其他用法
@ResponseBody可作用于方法和类:
- 方法:单个方法输出JSON数据,如上例
- 类:类的所有映射方法均输出JSON数据
当@ResponseBody作用于类时,@Controller和@ResponseBody可合写为@RestController
参考:
@Controller和@RestController的区别
Spring Mvc @ResponseBody String返回中文字符串乱码
javaweb学习总结(八)——HttpServletResponse对象(二)