1. Controller & RequestMapping
@Controller用来标注在类上,表示这个类是一个控制器类,可以用来处理http请求,通常会和@RequestMapping一起使用。这个注解上面有@Component注解,说明被@Controller标注的类会被注册到spring容器中,value属性用来指定这个bean的名称
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@RequestMapping表示请求映射,一般用在我们自定义的Controller类上或者Controller内部的方法上。
通过这个注解指定配置一些规则,满足这些规则的请求会被标注了@RequestMapping的方法处理。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
/**
* 限制url
*/
@AliasFor("path")
String[] value() default {};
/**
* 限制url
*/
@AliasFor("value")
String[] path() default {};
/**
* 限制http请求的method
*/
RequestMethod[] method() default {};
/**
* 限制请求的参数
*/
String[] params() default {};
/**
* 限制请求头
*/
String[] headers() default {};
/**
* 限制Content-Type的类型(客户端发送数据的类型)
*/
String[] consumes() default {};
/**
* 限制Accept的类型(客户端可接受数据的类型)
*/
String[] produces() default {};
}
可以简化@RequestMapping的注解如下:
注解 | 相当于 |
@PostMapping | @RequestMapping(method=RequestMethod.POST) |
@GetMapping | @RequestMapping(method=RequestMethod.GET) |
@DeleteMapping | @RequestMapping(method=RequestMethod.DELETE) |
@PutMapping | @RequestMapping(method=RequestMethod.PUT) |
2. 接收请求中的参数
1. 通过注解获得参数值
@PathVariable可以接受url中的参数
@RequestParam接收url中get的参数或者form表单中的参数
还可以接收Servlet中的对象:HttpServletRequest、HttpServletResponse、HttpSession
看下面这个事例:
@RequestMapping("/test/{id}")
public void test2(@PathVariable("id") String id,
@RequestParam("name") String name,
HttpServletRequest request,
HttpServletResponse response,
HttpSession session) throws IOException {
String message = String.format("id=%s, name=%s, age=%s"
, id, name, request.getParameter("age"));
response.getWriter().println(message);
}
2. 通过对象接收参数
事例如下:
@Data
@ToString
public class User {
private String name;
private String age;
}
@RequestMapping("/test3")
public void test3(User user, HttpServletResponse response) throws IOException {
response.getWriter().println(user);
}
3. 通过@RequestBoy接收请求的json数据
需求添加jackson包的依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
确保Spring配置文件包括如下配置
<mvc:annotation-driven />
示例代码:
@RequestMapping(value = "/test4", method = RequestMethod.POST)
public void test4(@RequestBody User user, HttpServletResponse response) throws IOException {
response.getWriter().println(user);
}
通过fiddler测试如下:
4. 通过MutlipartFile接收上传的文件
增加maven依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
定义multipartResover
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSizePerFile" value="#{10*1024*1024}"/>
<property name="maxUploadSize" value="#{100*1024*1024}"/>
</bean>
示例代码如下:
@RequestMapping(value = "/test5", method = RequestMethod.POST)
public void test5(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws IOException {
InputStream inputStream = file.getInputStream();
String s = IOUtils.toString(inputStream, "utf-8");
response.getWriter().println(s);
}
通过fiddler测试如下:
4. 其它注解
接收Http Header的内容@RequestHeader
接收cookie的内容@CookieValue
@RequestAttribute以及@SessionAttribute
事例:
@GetMapping("/test7")
public String test7(HttpServletRequest request,
HttpSession session){
request.setAttribute("age", "25");
session.setAttribute("hobby", "reading");
return "forward:/test6";
}
@RequestMapping("/test6")
public void test6(@RequestHeader("User-Agent") String userAgent,
@CookieValue("name") String name,
@RequestAttribute("age") String age,
@SessionAttribute("hobby") String hobby,
HttpServletResponse response) throws IOException {
String message = String.format("userAgent=%s, name=%s, age=%s, hobby=%s"
, userAgent, name, age, hobby);
response.getWriter().println(message);
}
fidder发起请求:
3. 常见返回值
1. 返回ModelAndView
首先配置viewResolver,如下:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
代码如下:
@GetMapping("/test")
public ModelAndView test(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "hello");
modelAndView.setViewName("hello");
return modelAndView;
}
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
示例请求:
2. 返回视图名称
示例代码:
@GetMapping("/test2")
public String test2(Model model){
model.addAttribute("message", "hello2");
return "hello";
}
3. redirect以及forward重定向
@GetMapping("/test3")
public String test3(){
return "redirect:/example/test2";
}
@GetMapping("/test4")
public String test4(){
return "forward:/example/test2";
}
4. 通过@ResponseBody返回Json字符串
前提也是引入jackson的maven依赖
@GetMapping("/test5")
@ResponseBody
public User test5(){
User user = new User();
user.setName("Mike");
user.setAge("28");
return user;
}
测试结果如下:
@ResponseBody可以放到Controller上面,这样所有方法的返回就可以返回Json数据了,Spring还提供了简化的注解@RestController
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
5. 没有返回或者返回null
@GetMapping("/test1")
public void test(){
}
@GetMapping("/test2")
public Object test2(){
return null;
}
springmvc调用这些方法之后,请求就结束了,springmvc会认为在控制器的方法中响应已经被处理过了,不需要springmvc去处理了。
应用场景:当响应结果比较复杂的时候,springmvc无法处理这些响应结果的时候,我们可以在控制器的方法中使用response来主动控制输出的结果。比如下载文件、断点下载文件等比较复杂的响应,此时我们可以在处理器的方法中使用HttpServletResponse来自己控制输出的内容