Restful风格介绍
-
WebAPI
- 如果一个URL返回的不包含HTML,而是数据,那么这个URL就是一个WebAPI(web接 口)
-
Restful
- 按照Rest风格访问WebAPI的一种方式
-
Restful风格
- ①不同CRUD操作采用不同的请求方式
- ②后台的响应数据采用JSON格式
HiddenHttpMethodFilter过滤器
-
概述
- form表单只支持get、post请求,如果要支持put、delete就需要使用HiddenHttpMethodFilter过滤器
-
代码实现
<!--post 2 put--> <form th:action="@{/rest/post2Put}" method="post"> <input type="hidden" name="_method" value="put"> 消息:<input type="text" name="msg"><br> <button type="submit">提交</button> </form> <!--post 2 delete--> <form th:action="@{/rest/post2Delete}" method="post"> <input type="hidden" name="_method" value="delete"> 消息:<input type="text" name="msg"><br> <button type="submit">提交</button> </form>
//@RequestMapping(path = "/rest/post2Put",method = RequestMethod.PUT) @PutMapping("/rest/post2Put") public String post2Put(String msg){ System.out.println("msg = " + msg); return "demo01"; } @DeleteMapping("/rest/post2Delete") public String post2Delete(String msg){ System.out.println("msg = " + msg); return "demo01"; }
-
注意事项
- 只能使用post模拟put、delete
Restful风格查询用户
-
需求
- 根据id查询用户记录
-
分析
http://localhost:8080/framework27/user/selectUserById?id=1 : 之前 http://localhost:8080/framework27/user/1 : 现在 , GET请求
-
代码实现
<a th:href="@{/user/1}">Restful风格查询用户</a>
@GetMapping("/user/{userId}") public String selectUserById(@PathVariable Integer userId){ System.out.println("userId = " + userId); return "demo02"; }
Restful风格删除用户
-
需求
- 根据id删除用户记录
-
分析
http://localhost:8080/framework27/user/deleteUserById?id=1 : 之前 http://localhost:8080/framework27/user/1 : 现在 , DELETE请求
-
代码实现
@DeleteMapping("/user/{userId}") public String deleteUserById(@PathVariable Integer userId){ System.out.println("deleteUserById userId = " + userId); return "demo02"; }
<body> <div id="app"> <!--post 2 delete--> <form method="post" id="deleteUserForm"> <input type="hidden" name="_method" value="delete"> </form> <a id="myA" th:href="@{/user/1}" @click.prevent="deleteUserById()">Restful风格删除用户</a> </div> </body> <script th:src="@{/js/vue.js}"></script> <script> //3,form表单根据a标签的href属性值发起请求 var vue = new Vue({ el: "#app", data: {}, methods: { //1,点击a标签 deleteUserById() { console.log("deleteUserById"); //2,触发form表单 var formEle = document.getElementById("deleteUserForm"); var aEle = document.getElementById("myA"); //3,form表单根据a标签的href属性值发起请求 formEle.setAttribute("action", aEle.getAttribute("href")); formEle.submit(); } } }) </script>
Restful风格添加用户
-
需求
- 添加用户记录
-
分析
http://localhost:8080/framework27/user/addUser?userName=root&userPwd=root : 之前 http://localhost:8080/framework27/user?userName=root&userPwd=root: 现在 , POST请求
-
代码实现
@PostMapping("/user") public String addUser(User inputUser){ System.out.println("addUser user = " + inputUser); return "demo04"; }
<form th:action="@{/user}" method="post" > <input type="text" name="userName" ><br> <input type="text" name="userPwd" ><br> <input type="submit" value="提交"> </form>
Restful风格登录功能
-
需求
- 登录功能
-
分析
http://localhost:8080/framework27/user/login?userName=root&userPwd=root : 之前,post http://localhost:8080/framework27/user?userName=root&userPwd=root: 现在 , POST请求
-
代码实现
@PostMapping("/user/login") public String login(User inputUser){ System.out.println("login user = " + inputUser); return "demo05"; }
<form th:action="@{/user/login}" method="post" > <input type="text" name="userName" ><br> <input type="text" name="userPwd" ><br> <input type="submit" value="提交"> </form>
Restful风格修改用户功能
-
需求
- 根据id修改用户记录
-
分析
http://localhost:8080/framework27/user/updateUserById?userId=1&userName=root&userPwd=root : 之前,post http://localhost:8080/framework27/user?userId=1&userName=root&userPwd=root : 现在 , PUT请求
-
代码实现
@PutMapping("/user") public String updateUserById(User inputUser){ System.out.println("updateUserById user = " + inputUser); return "demo04"; }
<form th:action="@{/user}" method="post" > <input type="hidden" name="_method" value="put"> <input type="hidden" name="userId" value="250"> <input type="text" name="userName" ><br> <input type="text" name="userPwd" ><br> <input type="submit" value="提交"> </form>
SpringMVC获取AJAX发送的普通参数
-
代码实现
<body> <div id="app"> <form th:action="@{/ajax/getParamter}" method="post" @submit.prevent="getParamter()"> <input type="text" name="userName" v-model="user.userName"><br> <input type="text" name="userPwd" v-model="user.userPwd"><br> <input type="submit" value="提交"> </form> </div> </body> <script th:src="@{/js/axios.js}"></script> <script th:src="@{/js/vue.js}"></script> <script> var vue = new Vue({ el: "#app", data: { user: { userId: 500, userName: "", userPwd: "" } }, methods: { getParamter() { var _this = this; //发起异步请求 /ajax/getParamter axios({ method: "get", url: "/framework27/ajax/getParamter", params: { userId: _this.user.userId, userName: _this.user.userName, userPwd: _this.user.userPwd } }).then(function (res) { var data = res.data; console.log(data); }) } } }) </script>
@RequestMapping("/ajax/getParamter") public void getParamter(User user, HttpServletResponse response) throws IOException { System.out.println("user = " + user); ResultVO resultVO = new ResultVO(true, "操作成功!", null); //resultVO 2 json字符串 response.setContentType("application/json;charset=utf-8"); String jsonStr = new ObjectMapper().writeValueAsString(resultVO); response.getWriter().write(jsonStr); }
SpringMVC获取AJAX发送的请求体json
-
代码实现1
<body> <div id="app"> <form th:action="@{/ajax/getParamter}" method="post" @submit.prevent="getParamter()"> <!--<input type="hidden" name="userId" value="250" v-model="user.userId">--> <input type="text" name="userName" v-model="user.userName"><br> <input type="text" name="userPwd" v-model="user.userPwd"><br> <input type="submit" value="提交"> </form> </div> </body> <script th:src="@{/js/axios.js}"></script> <script th:src="@{/js/vue.js}"></script> <script> var vue = new Vue({ el: "#app", data: { user: { userId: 500, userName: "", userPwd: "" } }, methods: { getParamter() { var _this = this; //发起异步请求 /ajax/getParamter axios({ method: "post", url: "/framework27/ajax/getParamter2", data: { userId: _this.user.userId, userName: _this.user.userName, userPwd: _this.user.userPwd } }).then(function (res) { console.log(res); }) } } }) </script>
@RequestMapping("/ajax/getParamter2") public void getParamter2(HttpServletRequest request, HttpServletResponse response) throws IOException { //①读取请求正文json BufferedReader bufferedReader = request.getReader(); String content = null; StringBuffer sb = new StringBuffer(); while ((content = bufferedReader.readLine()) != null) { sb.append(content); } String inputJsonStr = sb.toString(); //②jsonStr 2 javabean User user = new ObjectMapper().readValue(inputJsonStr, User.class); System.out.println("user = " + user); ResultVO resultVO = new ResultVO(true, "操作成功!", null); //resultVO 2 json字符串 response.setContentType("application/json;charset=utf-8"); String jsonStr = new ObjectMapper().writeValueAsString(resultVO); response.getWriter().write(jsonStr); }
-
代码实现2
@RequestMapping("/ajax/getParamter3") public void getParamter3(@RequestBody String inputJsonStr, HttpServletResponse response) throws IOException { //①读取请求正文json System.out.println("inputJsonStr = " + inputJsonStr); //② jsonStr2 javabean User user = new ObjectMapper().readValue(inputJsonStr, User.class); System.out.println("user = " + user); ResultVO resultVO = new ResultVO(true, "操作成功!", null); //resultVO 2 json字符串 response.setContentType("application/json;charset=utf-8"); String jsonStr = new ObjectMapper().writeValueAsString(resultVO); response.getWriter().write(jsonStr); }
-
代码实现3(推荐)
@RequestMapping("/ajax/getParamter4") public void getParamter4(@RequestBody User user, HttpServletResponse response) throws IOException { //①读取请求正文json //②jsonStr 2 javabean System.out.println("user = " + user); ResultVO resultVO = new ResultVO(true, "操作成功!", null); //resultVO 2 json字符串 response.setContentType("application/json;charset=utf-8"); String jsonStr = new ObjectMapper().writeValueAsString(resultVO); response.getWriter().write(jsonStr); }
SpringMVC响应json字符串
-
概述
- @ResponseBody : 将Handler方法的返回值作为响应正文返回给浏览器;如果返回值是一个javabean对象会自动将其转换为json字符串;同时也解决响应正文中文乱码问题。
-
代码实现1
@RequestMapping("/ajax/testResponse1") public void testResponse1(@RequestBody User user, HttpServletResponse response) throws IOException { //①读取请求正文json //②jsonStr 2 javabean System.out.println("user = " + user); response.setContentType("application/json;charset=utf-8"); ResultVO resultVO = new ResultVO(true, "操作成功!", null); //① resultVO 2 json字符串 String jsonStr = new ObjectMapper().writeValueAsString(resultVO); //② json字符串作为响应正文返回给客户端 response.getWriter().write(jsonStr); }
-
代码实现2
@ResponseBody @RequestMapping("/ajax/testResponse2") public String testResponse2(@RequestBody User user, HttpServletResponse response) throws IOException { //①读取请求正文json //②jsonStr 2 javabean System.out.println("user = " + user); ResultVO resultVO = new ResultVO(true, "操作成功!", null); //① resultVO 2 json字符串 String jsonStr = new ObjectMapper().writeValueAsString(resultVO); //② json字符串作为响应正文返回给客户端 return jsonStr;//以前,默认应该是逻辑视图名称;返回是一个json字符串并且是响应正文。 }
-
代码实现3(推荐)
@ResponseBody @RequestMapping("/ajax/testResponse3") public ResultVO testResponse3(@RequestBody User user, HttpServletResponse response) throws IOException { //①读取请求正文json //②jsonStr 2 javabean System.out.println("user = " + user); return new ResultVO(true, "操作成功!", null);//以前,默认应该是逻辑视图名称;返回是一个json字符串并且是响应正文。 }
异常映射概述
-
概述
- 一个项目中会包含很多个模块,各个模块需要分工完成。如果张三负责的模块按照 A 方案处 理异常,李四负责的模块按照 B 方法处理异常……各个模块处理异常的思路、代码、命名细 节都不一样,那么就会让整个项目非常混乱。
- 将异常类型和某个具体的视图关联起来,建立映射关系。可以通过 SpringMVC 框架来帮助 我们管理异常。
-
好处
- 让异常控制和核心业务解耦,二者各自维护,结构性更好
- 整个项目层面使用同一套规则来管理异常
注解开发异常处理器
-
以前
@RequestMapping("/exception/testException1") public String testException1(int num) { try { if (num == 1) { String str = null; System.out.println(str.length()); } else if (num == 2) { System.out.println(1 / 0); } } catch (NullPointerException e) { e.printStackTrace(); return "error1"; } catch (ArithmeticException e) { e.printStackTrace(); return "error2"; } return "index"; }
-
现在
@RequestMapping("/exception/testException2") public String testException2(int num) { if (num == 1) { String str = null; System.out.println(str.length()); } else if (num == 2) { System.out.println(1 / 0); } return "index"; }
@ControllerAdvice public class MyExceptionAdvice { @ExceptionHandler(NullPointerException.class) public String handleNullPointerException(){ System.out.println("MyExceptionAdvice handleNullPointerException"); return "error1"; } @ExceptionHandler(ArithmeticException.class) public String handleArithmeticException(){ System.out.println("MyExceptionAdvice handleArithmeticException"); return "error2"; } }
异常处理解决方案
-
代码实现
@ResponseBody @RequestMapping("/exception/testException3") public ResultVO testException3(int num) { try { if (num == 1) { String str = null; System.out.println(str.length()); } else if (num == 2) { System.out.println(1 / 0); } else if (num == 3) { //业务异常 (用户输入有问题) ,比如:输入为空、格式不对... throw new MyBusinessException("你老实点~~~"); } } catch (ArithmeticException e) { e.printStackTrace(); throw new MySystemException("系统异常!"); } catch (NullPointerException e) { e.printStackTrace(); throw new MySystemException("系统异常!"); } return new ResultVO(true, "操作成功!", null); }
@ControllerAdvice public class MyExceptionAdvice { @ResponseBody @ExceptionHandler(MyBusinessException.class) public ResultVO handleBusinessException(Exception e) { //提示用户 return new ResultVO(false, "操作失败!", e.getMessage()); } @ResponseBody @ExceptionHandler(MySystemException.class) public ResultVO handleSystemException(Exception e) { //安抚用户 //发送消息给开发人员 //记录日志 return new ResultVO(false, "操作失败!", e); } }
Spring、MyBatis、SpringMVC整合
-
开发步骤
-
①引入相关依赖
-
②Spring+MyBatis (mapper接口代理)
- 1.1,定义service接口及其实现子类
- 1.2,定义mapper接口
- 1.3,编写spring-core.xml
- 扫描注解
- 扫描所有的mapper接口代理对象
- 配置SqlSessionFactoryBean
- 配置DruidDataSource
- 1.4,测试通过
-
③整合SpringMVC
- 方式一,编写web.xml
- 配置DispatcherServlet
- 加载spring-mvc.xml
- 配置ContextLoaderListener
- 加载spring-core.xml
- 配置DispatcherServlet
- 方式二,编写web.xml
- 配置DispatcherServlet
- 加载spring-mvc.xml
- 加载spring-core.xml
- 配置DispatcherServlet
- 方式一,编写web.xml
-
③整合SpringMVC
<!--方式一--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-core.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
<!--方式二--> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-