@RestController。Controller 类上加了@RestController 注解,等价于在类中的每个方法上都加了@ResponseBody,全局返回 json 数据。
// JsonRestController.java
@RestController
@RequestMapping("/jsonrest")
public class JsonRestController {
@RequestMapping("/demo1")
public User demo1() {
User user = new User();
user.setUsername("张三");
user.setAge(12);
return user;
}
}
@RequestBody。将请求体中的 json 数据转换为 java 对象。
// JsonRestController.java
@RestController
@RequestMapping("/jsonrest")
public class JsonRestController {
@RequestMapping("/demo2")
public String demo2(@RequestBody User user) {
System.out.println(user);
return "kk";
}
}
FastJson 使用。
// pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
// mvc.xml
<mvc:annotation-driven>
<!-- 安装FastJson,转换器 -->
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 声明转换类型:json -->
<property name="supportedMediaTypes">
<list>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
异常解析器,统一处理 Controller 的异常。
// springmvc 全局异常解析
// 1 注解自动关联;2 bean 关联
//@Component
public class MyExecptionHandle implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView mv = new ModelAndView();
if (e instanceof ArithmeticException) {
mv.setViewName("error1");
} else if (e instanceof RuntimeException) {
mv.setViewName("error2");
} else if (e instanceof IOException) {
mv.setViewName("error3");
} else {
mv.setViewName("error4");
}
return mv;
}
}
// mvc.xml
<!-- 注册异常 bean -->
<bean class="com.baidu.day.text.exec.MyExecptionHandle"></bean>
// ExecController.java
@Controller
@RequestMapping("/exec")
public class ExecController {
@RequestMapping("/demo1")
public String demo1() {
int i = 10 / 0;
return "index";
}
@RequestMapping("/demo2")
public String demo2() {
if (true) {
throw new RuntimeException("出错啦");
}
return "index";
}
@RequestMapping("/demo3")
public String demo3() throws FileNotFoundException {
new FileInputStream("xxx");
return "index";
}
拦截器。
// MyInterceptor.java
public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截");
HttpSession session = request.getSession();
System.out.println("username" + session.getAttribute("username"));
if (session.getAttribute("username") != null) {
// 放行
return true;
}
// 拦截之前给出响应
response.sendRedirect(request.getContextPath() + "/login.jsp");
// 拦截
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("返回数据再次处理");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
System.out.println("资源回收");
}
}
// mvc.xml
<!-- 拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- /*,匹配一级;/**,匹配多级路径 -->
<mvc:mapping path="/inter/**"/>
<mvc:exclude-mapping path="/inter/login"/>
<!-- 处理拦截 -->
<bean class="com.baidu.day.text.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
// InterceptorController.java
@Controller
@RequestMapping("/inter")
public class InterceptorController {
@RequestMapping("login")
public String login(String username, String password) {
System.out.println(username + "\n" + password);
return "index";
}
@RequestMapping("/show")
public String show(HttpSession session) {
System.out.println("show");
return "index";
}
@RequestMapping("/del/all")
public String del() {
System.out.println("del");
return "index";
}
}
上传和下载。
// pom.xml
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
// upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="/file/upload" enctype="multipart/form-data">
<input type="file" name="files"><br>
<input type="submit" value="上传">
</form>
<a href="/file/download?name=从前有座山.txt">下载</a>
</body>
</html>
// mvc.xml
<!-- 文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="1024000" />
</bean>
// FileController.java
@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping("/upload")
@ResponseBody
public String fileUpload(MultipartFile files, HttpServletRequest request, User user) throws IOException {
String filename = files.getOriginalFilename();
String name = files.getName();
long size = files.getSize();
String contentType = files.getContentType();
String description = files.getResource().getDescription();
System.out.println(filename + "\n" + name + "\n" + size + "\n" + contentType + "\n" + description + "\n");
// 图片保存路径
// mac 路径有问题,此路径是 tomcat 临时路径,tomcat 重启后文件会清空。仅做测试用。
String realpath = request.getSession().getServletContext().getRealPath("/upload");
System.out.println(realpath);
File file = new File(realpath);
if (!file.exists()) {
file.mkdir();
}
files.transferTo(new File(realpath + "/" + filename));
return "success";
}
@RequestMapping("/download")
public void download(String name, HttpServletRequest request,HttpSession session, HttpServletResponse response) throws IOException {
String realpath = session.getServletContext().getRealPath("/upload");
String filepath = realpath + File.separator + name;
System.out.println(filepath);
// 中文编码后浏览器自动解码
String encode = URLEncoder.encode(name,"utf-8");
response.setHeader("Content-Disposition","attachment; filename=" + encode);
IOUtils.copy(new FileInputStream(filepath), response.getOutputStream());
}
}
验证码。
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
REST。是一种开发风格。不同的请求方式,对应相同的请求路径。
// 全局返回 json
@RestController
@RequestMapping("/rest")
public class MyRestController {
// 等同于 @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user")
public String getAll() {
System.out.println("getall");
return "ok";
}
@PostMapping("/user")
public String addUser() {
System.out.println("addUser");
return "ok";
}
}
跨域请求。
本地测试。可以复制一份当前工程,复制tomcat 服务包,Configurations 里改变http port = 8081 和 jmx.port 。
注意,启动相同 tomcat 服务包,无法演示跨域。
// http://localhost:8080/cross.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function () {
console.log("xx")
$("#click").click(function () {
console.log("dd")
$.ajax({
url: "http://localhost:8081/json/demo1",
type: "get",
xhrFields: {
// 跨域携带cookie
withCredentials: true
},
success: function (data) {
console.log(data)
},
error: function (error) {
console.log(error)
}
})
})
})
</script>
</head>
<body>
<input id="click" type="button" value="点击1">
</body>
</html>
// MyRestController.java
// http://localhost:8081/rest/user
// 全局返回 json
@RestController
@RequestMapping("/rest")
//允许其他域访问
@CrossOrigin("http://localhost:8080")
public class MyRestController {
// 等同于 @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user")
public String getAll() {
System.out.println("getall");
return "ok";
}
@PostMapping("/user")
public String addUser() {
System.out.println("addUser");
return "ok";
}
}
这里发送 ajax 请求。使用 jackson 返回字符串时,走了 ajax error 通道,报解析错误。返回能包装成 json 的对象或使用 fastjson 不会出现此问题。
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 安装FastJson,转换器 -->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 声明转换类型:json -->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=utf-8</value>
<value>text/html;charset=utf-8</value>
<value>application/x-www-form-urlencoded</value>
</list>
</property>
</bean>
<!-- <bean class="org.springframework.http.converter.StringHttpMessageConverter">-->
<!-- <property name="supportedMediaTypes">-->
<!-- <list>-->
<!-- <value>application/json;charset=utf-8</value>-->
<!-- <value>text/html;charset=utf-8</value>-->
<!-- <value>application/x-www-form-urlencoded</value>-->
<!-- </list>-->
<!-- </property>-->
<!-- </bean>-->
<!-- <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">-->
<!-- </bean>-->
</mvc:message-converters>
</mvc:annotation-driven>