SpringMvc基础知识
1、MVC基本概念
MVC(Model View Controller)是一种软件设计的框架模式,它采用模型(Model)-视图(View)-控制(controller)的方法把业务逻辑、数据与界面显示分离。把众多的业务逻辑聚集到一个部件里面,当然这种比较官方的解释是不能让我们足够清晰的理解什么是MVC的。用通俗的话来讲,MVC的理念就是把数据处理、数据展示(界面)和程序/用户的交互三者分离开的一种编程模式。
2、SpringMVC基本工作模式
- SpringMvc作用?
1.让我们能非常简单的设计出干净的Web层;
2. 进行更简洁的Web层的开发;
3. 天生与Spring框架集成(如IOC容器、AOP等);
4. 提供强大的约定大于配置的契约式编程支持;
5. 能简单的进行Web层的单元测试;
6. 支持灵活的URL到页面控制器的映射;
7. 非常容易与其他视图技术集成,如jsp、Velocity、FreeMarker等等,因为模型数据不放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用);
8. 非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API;
9. 支持灵活的本地化等解析;
10. 更加简单的异常处理;
11. 对静态资源的支持;
12. 支持Restful风格。
- 基本工作流程
1、用户发送请求到中央控制器,然后调用处理器映射器找到处理器,返回处理器对象到中央控制器,中央控制器又调用处理器适配器,返回ModelAndView对象,然后对视图进行解析,把数据渲染到动态页面上响应给客户端。
2、优势:
一. 清晰的角色划分:前端控制器(DispatcherServlet)、请求到处理器映射(HandlerMapping)、处
理器适配器(HandlerAdapter)、视图解析器(ViewResolver)、处理器或页面控制器(Controller)、验证器( Validator)、命令对象(Command 请求参数绑定到的对象就叫命令对象)、表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
二. 分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要;
三. 和Spring 其他框架无缝集成,是其它Web框架所不具备的;
四. 可适配,通过HandlerAdapter可以支持任意的类作为处理器;
五. 可定制性,HandlerMapping、ViewResolver等能够非常简单的定制;
六. 功能强大的数据验证、格式化、绑定机制;
七. 利用Spring提供的Mock对象能够非常简单的进行Web层单元测试;
八. 本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
九. 强大的JSP标签库,使JSP编写更容易。
还有比如RESTful(一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件,目前了解即可)风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。
3、SpringMVC环境快速搭建
- 导入Maven依赖
<dependencies>
<!--导入web依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.22</version>
</dependency>
<!--导入webMvc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
<!--导入servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<!--导入spring核心IOC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
<!--jackson核心依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<!--jackson数据绑定-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<!--jackson注解包-->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编译环境插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- jetty插件 -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.27.v20200227</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<!-- 设置端口 -->
<httpConnector>
<port>9999</port>
</httpConnector>
<!-- 设置项目路径 -->
<webAppConfig>
<contextPath>/test</contextPath>
</webAppConfig>
</configuration>
</plugin>
</plugins>
</build>
- 配置springMVC核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启mvc注解支持-->
<mvc:annotation-driven>
<!--mvc 请求映射 处理器与适配器配置 Http字符串转换 映射器Jackson2-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<!--开启静态文件处理器-->
<mvc:default-servlet-handler/>
<!--开启注解扫描包-->
<context:component-scan base-package="com.zwf.controller"/>
<!--配置视图解析器-->
<bean id="InternalResourceView" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀路径-->
<property name="prefix" value="/WEB-INF/page/"/>
<!--配置后缀路径文件-->
<property name="suffix" value=".jsp"/>
</bean>
<!--配置静态文件映射,让WEB-INF文件夹外的文件可以访问-->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"></mvc:resources>
</beans>
- 配置Web.xml文件
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置字符编码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置mvc中央控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:webmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 编写Controller层代码和webapp下的jsp或者html页面
4、URL 地址映射配置 & 参数绑定
1、Controller层通过@RequestMapping(value="")来设置访问路径,通过请求地址栏访问Controller层路径进行服务器访问或者前端表单提交。
2、@RequestMapping()有多个不同的参数,可以设置请求方式method、请求路径value、请求参数数组params,既可以声明在类上也可以声明在方法上,声明在类上表示访问的父路径,声明在方法上表示访问具体方法的访问路径。
3、@RequestParam(),可以设置默认值defaultValues和参数别名name,防止表单提交的参数与形参不一致,定义在形参旁边。
4、可以传递基本数据类型(int,char,boolean……)、引用数据类型(String,Integer……)、集合(List,Map,Set)、javabean对象,一般前台没有传递数据基本数据类型会报空指针异常,引用数据类型就为null,所以一般会设置形参默认值。
- 测试代码
package com.zwf.controller;
import com.zwf.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-09-04 10:25
*/
@Controller
//配置父路径
@RequestMapping("/servlet")
public class pageViewServlet {
@RequestMapping("/test1")
public ModelAndView getPage(Model m){
ModelAndView mv=new ModelAndView();
mv.setViewName("test");
m.addAttribute("infor","hello Mvc");
return mv;
}
//测试普通数据类型传值
/**
* 为了防止没传值报500服务端错误,我们使用基本数据类型 赋默认值
* @param a
* @param b
* @return
*/
@RequestMapping("/test2")
public ModelAndView TestParams(@RequestParam(defaultValue = "10") int a,@RequestParam(defaultValue = "20") int b){
ModelAndView modelAndView=new ModelAndView();
System.out.println(a+"<==========>"+b+"="+(a+b));
modelAndView.setViewName("test");
return modelAndView;
}
/**
* 为了防止没传值报500服务端错误,我们使用包装类 会显示null
*/
@RequestMapping("/test3")
public void TestParams1(Integer num,String value){
System.out.println("num"+"=="+num+"\t\tvalue"+"=="+value);
}
//method:指定接收的请求方式
@RequestMapping(value = "/bean",method = RequestMethod.POST )
//传递javaBean对象
public void TestParamsBean(User user){
System.out.println(user.toString());
}
- 前端测试代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<form action="servlet/bean" method="post">
<%--map集合的赋值--%>
<input type="text" name="maps['name']" value="张三"/>
<input type="text" name="maps['age']" value="20"/>
<!--list集合或者数组的赋值-->
<input type="text" name="ids[0]" value="12313"/>
<input type="text" name="ids[1]" value="789456"/>
<!--list集合对象的赋值 比如List<User>-->
<input type="text" name="lists[0].username" value="root"/>
<input type="text" name="lists[0].password" value="admin123"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
5、请求转发和重定向
1、Controller层中的方法可以通过返回字符串,以请求转发或者重定向方式跳转页面。
2、字符串中有redirect:表示重定向,forward:表示请求转发,请求转发可以携带request域的参数,而重定向无法获取参数,如果不编写redirect和forward默认表示请求转发并且走视图解析器进行页面名称拼接访问。
3、使用Model、ModelAndView、Map携带参数传参时,如果使用的重定向会发起表单提交方式(get/post),我们需要通过getParameter()或者${param.属性值}获取传递来的参数。如果使用的请求转发会自动转为request域请求参数,还有一种是拼接请求路径字符串发起请求,如果是重定向方式发起中文参数路径字符串拼接会乱码,我们可以通过形参RedirectAttributes对想存储中文参数然后发起请求,解决乱码或者Map、ModelAndView、Model存储参数解决乱码。
- 测试代码
package com.zwf.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-09-04 15:30
*/
@Controller
/*设置父路径*/
/**
* 请求转发和重定向
* 请求转发:forward:路径 相对路径要加上 /表示根路径 不会走视图解析器
* 重定向:redirect:路径 如果不加文件后缀名会默认走视图解析器
* 重定向请求参数方法:路径拼接 、redirectAttributes对象(可以解决中文参数乱码问题)
* Model、ModelMap、ModelAndView、Map,HttpServletRequest(重定向无法获取参数)等
*/
@RequestMapping("/test1")
public class forwardAndRedirectServlet {
//重定向页面跳转 test.jsp
//重定向路径相对路径 /表示根路径 如果不加后缀表示请求Controller层中的路径
@RequestMapping("/page1")
public String page1(){
return "redirect:/test.jsp";
}
//使用ModelAndView对象重定向请求
@RequestMapping("/page2")
public ModelAndView page2(){
ModelAndView mv=new ModelAndView();
mv.setViewName("redirect:/test.jsp");
return mv;
}
//测试请求转发参数作用域
//首先字符串拼接
@RequestMapping("/page3")
public String page3(){
//正常英文参数重定向请求不会乱码 如果使用中文就会乱码
//但是请求转发使用参数域不会乱码
return "redirect:/test.jsp?username=abc&password=123456";
}
//测试请求转发参数作用域
//首先字符串拼接
@RequestMapping("/page4")
public String page4(RedirectAttributes attributes){
//正常英文参数重定向请求不会乱码 如果使用中文就会乱码
//我们需要使用RedirectAttributes对象携带参数解决中文乱码问题
attributes.addAttribute("username","张三");
attributes.addAttribute("password","李四");
return "redirect:/test.jsp";
}
//使用Model携带参数
//重定向请求携带参数方式实际上就是表单提交方式 需要使用request.getParameter方法接收或者${param.属性名}
@RequestMapping("/page5")
public String page5(Model model){
//正常英文参数重定向请求不会乱码 如果使用中文就会乱码
//我们需要使用RedirectAttributes对象携带参数解决中文乱码问题
model.addAttribute("username","admin");
model.addAttribute("password","123456");
return "redirect:/test.jsp";
}
/**
* 使用ModelAndView对象携带参数重定向请求 可避免中文乱码问题
* @param mv
* @return
*/
@RequestMapping("/page6")
public ModelAndView page6(ModelAndView mv){
mv.addObject("username","张三");
mv.addObject("password","123456");
mv.setViewName("redirect:/test.jsp");
return mv;
}
/**
* Map键值对携带参数
* @param map
* @return
*/
@RequestMapping("/page7")
public String page7(Map<String, Object> map){
map.put("username","李四");
map.put("password","123456");
return "redirect:/test.jsp";
}
//原生HttpServletRequest内置对象携带参数
//由于重定向是多次请求,所以使用原生的request请求域参数无法获取。
@RequestMapping("/page8")
public String page8(HttpServletRequest request){
request.setAttribute("username","李思");
request.setAttribute("password","123456789");
return "redirect:/test.jsp";
}
//重定向到Controller层请求
@RequestMapping("/page9")
public String page9(HttpServletRequest request){
request.setAttribute("username","李思");
request.setAttribute("password","123456789");
return "redirect:/test";
}
@RequestMapping("/page10")
public String page10(Model model){
model.addAttribute("username","root");
model.addAttribute("password","123456");
return "redirect:/test";
}
}
*****************************************************************************************
package com.zwf.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-09-04 15:48
*/
/**
* forward:请求转发 如果返回字符串或者返回modelAndView对象中setViewName("")不写forward,会走视图解析器。
* @RequestMapping(params = {"abcd"}):访问路径:http://localhost:9999/test/?abcd
*/
@Controller
public class RedirectPage {
@RequestMapping(params = {"abcd"})
public void pages(HttpServletRequest request){
String username = request.getParameter("username");
String pwd =(String) request.getAttribute("password");
System.out.println("param-->username="+username);
System.out.println("attribute-->pwd="+ pwd);
System.out.println("测试重定向请求!");
}
//测试请求转发 默认不定义就是请求转发
@RequestMapping("/page1")
public String page1(Model model){
model.addAttribute("infor","hello forward!");
return "test"; //不写forward会走视图解析器,如果要跳转到根路径下的test.jsp文件,就要使用../../test
}
@RequestMapping("/page2")
public String page2(Model model){
model.addAttribute("username","hello forward!");
model.addAttribute("password","123456789");
return "forward:test.jsp"; //查找webapp目录下的test.jsp
}
@RequestMapping("/page3")
public ModelAndView page3(ModelAndView mv){
mv.addObject("username","hello forward!");
mv.addObject("password","123456789");
mv.setViewName("forward:/test.jsp");
return mv; //使用请求转发跳转页面携带参数域
}
@RequestMapping("/page4")
public String page4(Model model){
model.addAttribute("username","hello forward!");
model.addAttribute("password","123456789");
return "../../test"; //默认走视图解析器 可以通过跳转路径查找webapp目录下的test.jsp
}
@RequestMapping("/page5")
public String page5(Map<String, Object> map){
map.put("username","hello forward!");
map.put("password","123456789");
return "../../test"; //默认走视图解析器 可以通过跳转路径查找webapp目录下的test.jsp
}
@RequestMapping("/page6")
public String page6(Map<String, Object> map){
map.put("username","hello forward!");
map.put("password","123456789");
return "forward:/test12"; // 跳转到/test12 controller层
}
}
6、SpringMVC请求响应JSON字符串
@RequestBody是声明在实体类形参中,用于接收Ajax请求的json字符串对象。
@ReponseBody声明在方法上或者方法返回值前,用于响应json字符串到客户端。
Ajax必须要传递json对象字符串,设置contentType:'application/json'。
- 导入jackson依赖
<!--jackson核心依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<!--jackson数据绑定-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<!--jackson注解包-->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.3</version>
</dependency>
- 核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启mvc注解支持-->
<mvc:annotation-driven>
<!--mvc 请求映射 处理器与适配器配置 Http字符串转换 映射器Jackson2-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
- 测试代码
package com.zwf.controller;
import com.zwf.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
import java.util.List;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-09-04 19:38
*/
@Controller
//设置json数据类
public class JsonController {
@RequestMapping("/json")
@ResponseBody //响应json字符串格式给客户端
public User getUser(){
User user=new User();
user.setUsername("root");
user.setPassword("123456789");
List<String> list= Arrays.asList("one","two","three","four","five","six");
user.setIds(list);
return user;
}
//请求json字符串(字符串)格式给controller层 然后响应给json字符串给客户端
@RequestMapping("/json1")
@ResponseBody
public User responseUser(@RequestBody User user){
System.out.println(user);
return user;
}
}
- 前端代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试发送JSON请求</title>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
</head>
<body>
<button type="button" onclick="test1()">点击发送Ajax请求1</button>
<button type="button" onclick="test2()">点击发送Ajax请求2</button>
</body>
<script type="text/javascript">
function test1(){
$.ajax({
type:'post',
url:'json',
dataType:"json",
success:function (data){
console.log(data);
}
});
}
function test2(){
$.ajax({
type:'post',
url:'json1',
// dataType:"json",
contentType:'application/json',
//请求发送json字符串
data:'{"username":"root","password":"123456","hobby":["打羽毛球","下象棋","下围棋","跑步"]}',
success:function (data){
console.log(data);
}
});
}
</script>
</html>
7、拦截器(Interceptor)
1、我们可以通过拦截器处理用户权限、字符编码过滤,非法访问页面等操作,可以配置多个拦截器,先配置的preHandle()先执行,然后执行拦截前的操作,然后后配置的postHandle()先执行,处理执行handle方法后,解析视图前的操作,最后后配置的afterCompletion()先执行,处理解析视图完成后的操作,我们一般定义拦截前的逻辑处理,定义在preHandle()方法中。
2、定义Interceptor拦截器有二种方式
一、继承HandleInterceptorAdapter适配器类,重写preHandle();
二、实现HandleInterceptor接口,实现preHandle()方法;(推荐使用)
3、最后在MVC核心配置文件中配置。
- MVC核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--配置拦截器,可配置多个拦截器-->
<mvc:interceptors>
<!-- <mvc:interceptor>
<!–拦截所有请求–>
<mvc:mapping path="/**"/>
<bean class="com.zwf.interceptor.InterceptorDemo1"/>
</mvc:interceptor>
<!–配置多个拦截器–>
<mvc:interceptor>
<!–拦截所有请求–>
<mvc:mapping path="/**"/>
<bean class="com.zwf.interceptor.InterceptorDemo2"/>
</mvc:interceptor>-->
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/**"/>
<!--放行指定的请求或者页面-->
<mvc:exclude-mapping path="/user/login"/>
<mvc:exclude-mapping path="/upload/file"/>
<mvc:exclude-mapping path="/upload/file1"/>
<bean class="com.zwf.interceptor.LoginIntercetor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
- 测试代码
public class InterceptorDemo1 implements HandlerInterceptor {
//实现PreHandle() afterHandle()
/**
* handle方法执行前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("handle1方法执行前,也是业务逻辑代码编写……");
//false 表示不执行handle方法 true表示执行handle方法
return true;
}
/**
* handle方法执行后 视图解析前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("handle1方法执行后,视图解析前…… postHandle");
}
/**
* 拦截器最终完成时
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("handle1方法执行后,视图解析后…… afterCompletion……");
}
}
/**
* 继承HandlerInterceptorAdapter父类 此方法已过时
*/
public class InterceptorDemo2 extends HandlerInterceptorAdapter{
//实现PreHandle() afterHandle()
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("handle2方法执行前,也是业务逻辑代码编写……");
//false 表示不执行handle方法 true表示执行handle方法
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("handle2方法执行后,视图解析前…… postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("handle2方法执行后,视图解析后…… afterCompletion……");
}
}
8、文件上传
1、文件上传也是springMVC中的常见功能,这种功能主要用于上传头像。
2、使用文件上传要导入apache旗下的commons-fileUpload包,然后配置上传文件配置。
3、可以上传单个或者多个文件。
- 导入Maven坐标
<!--先导入上传文件依赖 commons-fileUpload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
- 配置核心配置文件
<!--配置上传文件路径 id="multipartResolver" id一定要是multipartResolver大小写也不能变-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--配置上传文件大小最大值 单位Byte-->
<property name="maxUploadSize" value="10485760"/>
<!--设置临时文件大小 单位Byte 10kb 超过10kb存放临时文件夹 是一个阈值-->
<property name="maxInMemorySize" value="10240"/>
</bean>
- 测试代码
@Controller
@RequestMapping("/upload")
public class UploadFileController {
@RequestMapping("/file")
public String getUploadFile(@RequestParam("uploadFile")MultipartFile uploadFile,HttpServletRequest request){
//最原始的方式
// MultipartHttpServletRequest req=(MultipartHttpServletRequest) request;
// MultipartFile uploadFile = req.getFile("uploadFile");
//获取上传表单的文件对象
if(!uploadFile.isEmpty()){
//获取文件名 截取文件后缀
String originalFilename = uploadFile.getOriginalFilename();
String suffixName=originalFilename.substring(originalFilename.lastIndexOf('.'));
//生成随机文件名
long l = System.currentTimeMillis();
String fileName=String.valueOf(l)+suffixName;
//获取存放文件的真实路径
String realPath = request.getSession().getServletContext().getRealPath("/upload/");
File file=new File(realPath);
if(!file.exists()){
file.mkdirs();
}
try {
uploadFile.transferTo(new File(realPath,fileName));
request.setAttribute("msg","文件上传成功!");
} catch (IOException e) {
request.setAttribute("msg","文件上传失败!");
throw new RuntimeException(e);
}
}else {
request.setAttribute("msg","文件不存在!");
}
return "uploadSuccess";
}
//多文件上传
@RequestMapping("/file1")
public String getUploadDemo(@RequestParam("uploadFile") List<MultipartFile> upload, HttpServletRequest request){
if(upload!=null&&upload.size()>0){
for(int i=0;i<upload.size();i++){
MultipartFile multipartFile = upload.get(i);
if(!multipartFile.isEmpty()){
String original = multipartFile.getOriginalFilename();
String suffixName=original.substring(original.lastIndexOf('.'));
String newName=String.valueOf(System.currentTimeMillis())+suffixName;
ServletContext context = request.getSession().getServletContext();
String realPath = context.getRealPath("/upload/");
File file=new File(realPath);
if(!file.exists()){
file.mkdirs();
}
try {
multipartFile.transferTo(new File(realPath,newName));
request.setAttribute("msg","上传文件成功!");
} catch (IOException e) {
request.setAttribute("msg","上传文件失败!");
throw new RuntimeException(e);
}
}else {
request.setAttribute("msg","不存在上传文件!");
}
}
}
return "uploadSuccess";
}
}
- 前端测试代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试上传文件</title>
</head>
<body>
<form action="upload/file" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile"/>
<input type="submit" value="上传">
</form>
<hr/>
多文件上传
<form action="upload/file1" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile"/>
<input type="file" name="uploadFile"/>
<input type="file" name="uploadFile"/>
<input type="file" name="uploadFile"/>
<input type="submit" value="上传">
</form>
</body>
</html>
9、SSM框架整合
- 先导入Maven依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zwf</groupId>
<artifactId>SSMDemo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SSMDemo Maven Webapp</name>
<dependencies>
<!--
要导入spring-context spring-tx
spring-webmvc spring-mvc aspectweaver mysql-connection
jackson-core jackson-databind jackson-annotations
mybatis-spring spring-aop c3p0 pageHelper分页插件 log4j
spring-web mybatis spring-test spring-jdbc
-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.22</version>
</dependency>
<!--切面织入包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!--编译java目录下的配置文件和resources目录-->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<!--jetty插件和编译插件-->
<plugins>
<!-- 编译环境插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- jetty插件 -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.27.v20200227</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<!-- 设置端口 -->
<httpConnector>
<port>9999</port>
</httpConnector>
<!-- 设置项目路径 -->
<webAppConfig>
<contextPath>/ssm</contextPath>
</webAppConfig>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 编写mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置日志文件-->
<settings>
<setting name="logImpl" value="LOG4j"/>
</settings>
<!--设置别名-->
<typeAliases>
<package name="com.zwf.ssm.pojo"/>
</typeAliases>
<!--引入分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
</configuration>
- 编写数据库连接信息配置文件
jdbc.user=root
jdbc.pwd=root@123456
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=UTF-8&serverTimeZone=Asia/shanghai&useSSL=true
jdbc.driver=com.mysql.cj.jdbc.Driver
- 编写spring核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启扫描包注解-->
<context:component-scan base-package="com.zwf.ssm">
<!--排除controller-->
<context:exclude-filter type="annotation" expression="com.zwf.ssm.controller"/>
</context:component-scan>
<!--引入properties文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置c3p0连接池-->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--引入数据连接池-->
<property name="dataSource" ref="c3p0"/>
</bean>
<!--开启切面自动代理 注解开发-->
<aop:aspectj-autoproxy/>
<!--声明事务-->
<tx:advice transaction-manager="transactionManager" id="advice">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="query*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<!--引入事务-->
<aop:advisor pointcut-ref="cutPoint" advice-ref="advice"/>
<aop:aspect ref="customerAspect">
<aop:pointcut id="cutPoint" expression="execution(* com.zwf.ssm.service..*(..))"/>
<!--引入环绕通知-->
<!-- <aop:around method="getRound" pointcut-ref="cutPoint"/>-->
</aop:aspect>
</aop:config>
<!--开启事务注解驱动-->
<tx:annotation-driven/>
<!--引入mybatis配置-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="c3p0"/>
<property name="mapperLocations" value="classpath:com/zwf/ssm/mapper/*.xml"/>
<property name="configLocation" value="classpath:mybatis.xml"/>
</bean>
<!--配置mapper扫描映射包 扫描dao包-->
<bean id="mappers" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zwf.ssm.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
- 配置springMVC核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启mvc注解扫描-->
<context:component-scan base-package="com.zwf.ssm.controller"/>
<!--开启默认静态资源处理器-->
<mvc:default-servlet-handler/>
<!--开启注解驱动-->
<mvc:annotation-driven>
<!--配置类型转换 可以自动转json 可以不使用第三方工具转json字符串响应-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<!--配置视图解析器-->
<bean id="internalView" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置上传文件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置配置临时文件大小-->
<property name="maxInMemorySize" value="102400"/>
<!--配置上传最大文件大小-->
<property name="maxUploadSize" value="102400"/>
</bean>
<!--配置全局异常-->
<bean id="globalException" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 配置默认异常页面-->
<property name="defaultErrorView" value="error"/>
<!-- 设置变量值 通用所有页面-->
<property name="exceptionAttribute" value="ex"/>
<!-- 自定义配置异常页面的分配-->
<property name="exceptionMappings" >
<!-- 定义自定义异常 标签内定义跳转页面 走视图解析器-->
<props>
<prop key="com.zwf.ssm.exception.LogicException">logic</prop>
<prop key="com.zwf.ssm.exception.commonException">common</prop>
</props>
</property>
</bean>
</beans>
- 配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!--加载spring核心配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置处理字符乱码-->
<filter>
<filter-name>encode</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>/**</url-pattern>
</filter-mapping>
<!--加载springMVC-->
<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:mvc-context.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>
<!--处理未捕获的异常-->
<!--根据响应码处-->
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
<!--根据异常类型捕获异常-->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/errorDemo.jsp</location>
</error-page>
</web-app>
- 配置log4j日志核心配置文件
log4j.rootLogger=DEBUG,console,dailyFile,im
log4j.additivity.org.apache=true
# 控制台(console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 日志文件(logFile)
log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/bigCode/SSMDemo/logs/log4j.txt
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 回滚文件(rollingFile)
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/bigCode/SSMDemo/logs/log4j.txt
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 定期回滚日志文件(dailyFile)
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.Threshold=DEBUG
log4j.appender.dailyFile.ImmediateFlush=true
log4j.appender.dailyFile.Append=true
log4j.appender.dailyFile.File=D:/bigCode/SSMDemo/logs/log4j.txt
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 应用于socket
#log4j.appender.socket=org.apache.log4j.RollingFileAppender
#log4j.appender.socket.RemoteHost=localhost
#log4j.appender.socket.Port=5001
#log4j.appender.socket.LocationInfo=true
## Set up for Log Factor 5
#log4j.appender.socket.layout=org.apache.log4j.PatternLayout
#log4j.appender.socket.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
## Log Factor 5 Appender
#log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
#log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 发送日志到指定邮件
#log4j.appender.mail=org.apache.log4j.net.SMTPAppender
#log4j.appender.mail.Threshold=FATAL
#log4j.appender.mail.BufferSize=10
#log4j.appender.mail.From = [email protected]
#log4j.appender.mail.SMTPHost=mail.com
#log4j.appender.mail.Subject=Log4J Message
#log4j.appender.mail.To= [email protected]
#log4j.appender.mail.layout=org.apache.log4j.PatternLayout
#log4j.appender.mail.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 应用于数据库
#log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.database.URL=jdbc:mysql://localhost:3306/test
#log4j.appender.database.driver=com.mysql.jdbc.Driver
#log4j.appender.database.user=root
#log4j.appender.database.password=
#log4j.appender.database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
#log4j.appender.database.layout=org.apache.log4j.PatternLayout
#log4j.appender.database.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 自定义Appender
#log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
#log4j.appender.im.host = mail.cybercorlin.net
#log4j.appender.im.username = username
#log4j.appender.im.password = password
#log4j.appender.im.recipient = [email protected]
#log4j.appender.im.layout=org.apache.log4j.PatternLayout
#log4j.appender.im.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
- 然后编写测试代码(详见SSM代码)
10、ResutFul风格
1、ResutFul风格是一种基于Http请求的编码规范,它不是语法,只是一种标准的规范,可以让人更加清晰认识到每个请求是什么操作,同时可以通过地址栏携带请求参数进行形参传值。
2、常见的请求的方式有post(定义为添加数据操作)、get(查询数据操作)、delete(删除数据操作)、put(更新数据操作)。
3、浏览器请求地址栏,默认访问使用的是get请求方式,如果要测试其他方式,我们可以用postman工具,对接口进行测试。
- 测试代码
/**
* restFul风格
*/
@Controller
public class UserController extends HandExceptionAnnotation {
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
public @ResponseBody List<User> queryAllUser(@PathVariable Integer id){
List<User> users = userService.queryAllUserById(id);
return users;
}
@PostMapping("/users")
public @ResponseBody String saveUser(@RequestBody User user){
Integer row = userService.saveUser(user);
if(row>0){
return "数据添加成功!";
}
return "数据添加失败!";
}
@PutMapping("/users")
public @ResponseBody String updateUser(@RequestBody User user){
Integer row = userService.updateUser(user);
if(row>0){
return "数据更新成功!";
}
return "数据更新失败!";
}
@DeleteMapping ("/users/{id}")
public @ResponseBody String deleteUser(@PathVariable Integer id){
Integer row = userService.deleteUser(id);
if(row>0){
return "数据删除成功!";
}
return "数据删除失败!";
}
@GetMapping( "/test6666")
public ModelAndView throwsExceptionPage(){
//执行到异常 跳转到相应的异常页面
int a=10/0;
// if(1==1){
//
// throw new LogicException();
// }
ModelAndView mv=new ModelAndView("pageError");
return mv;
}
- 使用postman工具对接口进行测试(下载地址:https://dl.pstmn.io/download/latest/win64)
11、自定义异常
1、有三种异常自定义方式:
一、核心配置定义。 SimpleMappingHandleExceptionResolver
二、实现接口定义。 HandleExceptionResolver
三、继承注解类定义。 @ExceptionHandle
- 第一种方式(在mvc核心配置文件中配置)
<!--配置全局异常-->
<bean id="globalException" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 配置默认异常页面-->
<property name="defaultErrorView" value="error"/>
<!-- 设置变量值 通用所有页面-->
<property name="exceptionAttribute" value="ex"/>
<!-- 自定义配置异常页面的分配-->
<property name="exceptionMappings" >
<!-- 定义自定义异常 标签内定义跳转页面 走视图解析器-->
<props>
<prop key="com.zwf.ssm.exception.LogicException">logic</prop>
<prop key="com.zwf.ssm.exception.commonException">common</prop>
</props>
</property>
</bean>
- 测试代码
@GetMapping( "/test6666")
public ModelAndView throwsExceptionPage(){
//执行到异常 跳转到默认的异常页面
int a=10/0;
// if(1==1){
//
// throw new LogicException();
// }
ModelAndView mv=new ModelAndView("pageError");
return mv;
}
- 第二种定义方式(推荐使用)
package com.zwf.ssm.exception;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Mr Zeng
* @version 1.0
* @date 2023-09-07 8:43
*/
/**
* 推荐使用此方法 定义自定义异常 无注入 降低耦合度
*/
@Component //交给springIOC容器管理
public class CustomerException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv=new ModelAndView();
mv.addObject("ex",ex.getMessage());
//默认跳转的页面error.jsp 走视图解析器
mv.setViewName("error");
if(ex instanceof commonException){
commonException e=(commonException) ex;
mv.addObject("ex",e.getMessage());
mv.setViewName("common");
return mv;
}else if(ex instanceof LogicException){
LogicException e=(LogicException)ex;
mv.addObject("ex",e.getMessage());
mv.setViewName("logic");
return mv;
}
return mv;
}
}
- 测试代码
@GetMapping( "/test6666")
public ModelAndView throwsExceptionPage(){
//执行到异常 跳转到默认的异常页面
int a=10/0;
// if(1==1){
//
// throw new LogicException();
// }
ModelAndView mv=new ModelAndView("pageError");
return mv;
}
- 第三种定义方式
/**
* 使用此类异常声明时 要继承此类
*/
public class HandExceptionAnnotation {
//异常注解
@ExceptionHandler
public String getException(HttpServletRequest request, HttpServletResponse response,Exception e){
request.setAttribute("ex",e.getMessage()); //默认页面响应错误
if(e instanceof commonException){
commonException ex=(commonException) e;
request.setAttribute("ex",ex.getMessage());
return "common";
}
if(e instanceof LogicException){
LogicException ex=(LogicException) e;
request.setAttribute("ex",ex.getMessage());
return "common";
}
return "error";
}
}
- 测试代码 (使用时继承自定义异常类)
@Controller
public class UserController extends HandExceptionAnnotation {
@GetMapping( "/test6666")
public ModelAndView throwsExceptionPage(){
//执行到异常 跳转到默认的异常页面
int a=10/0;
// if(1==1){
//
// throw new LogicException();
// }
ModelAndView mv=new ModelAndView("pageError");
return mv;
}
}
标签:return,log4j,SpringMvc,appender,ModelAndView,org,基础知识,public
From: https://www.cnblogs.com/smallzengstudy/p/17691014.html