Краткое изложение SpringMVC на 5000 слов, я думаю, вам это понадобится

Java
Краткое изложение SpringMVC на 5000 слов, я думаю, вам это понадобится

карта разума

Публичный аккаунт WeChat был открыт: [энтузиаст Java-технологий], если вы еще не обратили внимания, не забудьте обратить внимание~

Статья была включена в мою подборку на Github, добро пожаловать в Star:GitHub.com/Yehongqin/Лай…

Обзор

SpringMVC — наиболее известная среда, поскольку самой популярной встроенной средой MVC SpringBoot является SpringMVC. Моя мотивация для написания этой статьи состоит в том, чтобы просмотреть, обобщить и заново понять SpringMVC.

Чтобы понять SpringMVC, сначала посмотрите на схему процесса:

Из блок-схемы мы видим:

  • Получите запрос запроса от внешнего интерфейса.
  • Найдите соответствующий процессор для обработки запроса в соответствии с путем сопоставления и вернитесь в ModelAndView после завершения обработки.
  • Выполните синтаксический анализ представления, визуализацию представления и возврат результатов ответа.

Резюме:Получайте параметры, определяйте пути сопоставления, переходы на страницы и возвращайте результаты ответов..

Конечно, это только самая основная основная функция, в дополнение кОпределение перехватчиков, глобальная обработка исключений, загрузка и выгрузка файлови т.п.

1. Создание проекта

В предыдущем старом проекте из-за отсутствия SpringBoot нет автоматической настройки, поэтому нужно использоватьweb.xmlфайл для определения DispatcherServlet. Теперь интернет-приложения в основном используют SpringBoot, поэтому я буду использовать SpringBoot непосредственно для демонстрации. Это очень просто, просто введите зависимости:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. Определите контроллер

Существует пять способов определения обработчиков контроллеров с помощью SpringMVC.

2.1 Реализация интерфейса контроллера

Ранний SpringMVC был определен следующим образом:

/**
 * @author Ye Hongzhi 公众号:java技术爱好者
 * @name DemoController
 * @date 2020-08-25 22:28
 **/
@org.springframework.stereotype.Controller("/demo/controller")
public class DemoController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //业务处理
        return null;
    }
}

2.2 Реализация интерфейса HttpRequestHandler

Аналогично первому способу, но также за счет реализации интерфейса:

/**
 * @author Ye Hongzhi 公众号:java技术爱好者
 * @name HttpDemoController
 * @date 2020-08-25 22:45
 **/
@Controller("/http/controller")
public class HttpDemoController implements HttpRequestHandler{
    @Override
    public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
        //业务处理
    }
}

2.3 Реализация интерфейса сервлета

Этот метод устарел, но его можно увидеть здесьНижний слой SpringMVC по-прежнему является сервлетом..

@Controller("/servlet/controller")
public class ServletDemoController implements Servlet {
    //以下是Servlet生命周期方法
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
    }
}

Поскольку этот метод не рекомендуется, этот адаптер не загружается по умолчанию, вам необходимо добавить:

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public SimpleServletHandlerAdapter simpleServletHandlerAdapter() {
        return new SimpleServletHandlerAdapter();
    }
}

2.4 Использование @RequestMapping

Этот метод используется чаще всего, потому что в приведенных выше определениях метода необходимо использовать класс для определения пути, что приведет к большому количеству классов. Использование аннотаций относительно легкое.

@Controller
@RequestMapping("/requestMapping/controller")
public class RequestMappingController {

    @RequestMapping("/demo")
    public String demo() {
        return "HelloWord";
    }
}

2.4.1 Поддержка спокойного стиля

и поддержкаСпокойный стиль,использоватьmethodАтрибуты определяют, как работать с ресурсами:

	@RequestMapping(value = "/restful", method = RequestMethod.GET)
    public String get() {
        //查询
        return "get";
    }

    @RequestMapping(value = "/restful", method = RequestMethod.POST)
    public String post() {
        //创建
        return "post";
    }

    @RequestMapping(value = "/restful", method = RequestMethod.PUT)
    public String put() {
        //更新
        return "put";
    }

    @RequestMapping(value = "/restful", method = RequestMethod.DELETE)
    public String del() {
        //删除
        return "post";
    }

2.4.2 Поддержка стиля Ant

	//匹配 /antA 或者 /antB 等URL
    @RequestMapping("/ant?")
    public String ant() {
        return "ant";
    }

    //匹配 /ant/a/create 或者 /ant/b/create 等URL
    @RequestMapping("/ant/*/create")
    public String antCreate() {
        return "antCreate";
    }

    //匹配 /ant/create 或者 /ant/a/b/create 等URL
    @RequestMapping("/ant/**/create")
    public String antAllCreate() {
        return "antAllCreate";
    }

2.5 Использование HandlerFunction

Последний заключается в использовании функционального интерфейса HandlerFunction, которыйSpring5.0Метод, представленный позже, в основном используется для разработки адаптивных интерфейсов, то есть разработки Webflux.

Если вы заинтересованы, вы можете поискать соответствующую информацию в Интернете, чтобы узнать об этом. Это может занять много места, поэтому я не буду вдаваться в подробности здесь.

3. Получить параметры

После определения контроллера вам необходимо получить параметры, переданные внешним интерфейсом, как их получить.

3.1 Получение общих параметров

Просто напишите полученное имя параметра в методе сопоставления @RequestMapping:

@RequestMapping(value = "/restful", method = RequestMethod.POST)
public String post(Integer id, String name, int money) {
    System.out.println("id:" + id + ",name:" + name + ",money:" + money);
    return "post";
}

3.2 Привязка имени параметра @RequestParam

Если вы не хотите использовать имя параметра в качестве имени параметра, вы можете использовать @RequestParam для привязки имени параметра:

	/**
     * value: 参数名
     * required: 是否request中必须包含此参数,默认是true。
     * defaultValue: 默认参数值
     */
    @RequestMapping(value = "/restful", method = RequestMethod.GET)
    public String get(@RequestParam(value = "userId", required = false, defaultValue = "0") String id) {
        System.out.println("id:" + id);
        return "get";
    }

3.3 Параметры пути @PathVariable

Сопоставьте параметры заполнителя {xxx} в URL-адресе с входными параметрами метода операции через @PathVariable. Демонстрационный код выглядит следующим образом:

@RequestMapping(value = "/restful/{id}", method = RequestMethod.GET)
public String search(@PathVariable("id") String id) {
    System.out.println("id:" + id);
    return "search";
}

3.4 @RequestHeader связывает свойства заголовка запроса

Как получить информацию из заголовка запроса?

Используйте аннотацию @RequestHeader, использование аналогично @RequestParam:

	@RequestMapping("/head")
    public String head(@RequestHeader("Accept-Language") String acceptLanguage) {
        return acceptLanguage;
    }

3.5 @CookieValue связывает запрошенное значение cookie

Получите значение куки в запросе:

	@RequestMapping("/cookie")
    public String cookie(@CookieValue("_ga") String _ga) {
        return _ga;
    }

3.6 Привязка параметров запроса к объектам POJO

Определен класс сущности пользователя:

public class User {
    private String id;
    private String name;
    private Integer age;
    //getter、setter方法
}

Определите метод действия @RequestMapping:

	@RequestMapping("/body")
    public String body(User user) {
        return user.toString();
    }

Пока параметр запроса совпадает с именем свойства, он автоматически заполняется в объекте пользователя:

3.6.1 Поддержка каскадных свойств

Теперь есть класс Address для хранения адресной информации:

public class Address {
    private String id;
    private String name;
    //getter、setter方法
}

Добавьте атрибут адреса для пользователя:

public class User {
    private String id;
    private String name;
    private Integer age;
    private Address address;
    //getter、setter方法
}

При передаче параметров, если переданы адреса address.name и address.id, они будут заполнены автоматически:

3.6.2 @InitBinder разрешает конфликт имен свойств при получении нескольких объектов

Если есть два объекта POJO с одинаковым именем свойства, нет ли конфликта? Например, пользователь и адрес только что имеют два атрибута, id и name, если они получены одновременно, они будут конфликтовать:

	//user和address都有id和name这两个属性	
	@RequestMapping(value = "/twoBody", method = RequestMethod.POST)
    public String twoBody(User user, Address address) {
        return user.toString() + "," + address.toString();
    }

На этом этапе вы можете использовать @InitBinder для привязки имени параметра:

	@InitBinder("user")
    public void initBindUser(WebDataBinder webDataBinder) {
        webDataBinder.setFieldDefaultPrefix("u.");
    }

    @InitBinder("address")
    public void initBindAddress(WebDataBinder webDataBinder) {
        webDataBinder.setFieldDefaultPrefix("addr.");
    }

3.6.3 @Requestbody автоматически анализирует строки JSON и инкапсулирует их в объекты

Внешний интерфейс передает строку json и автоматически преобразует ее в объект pojo. Демонстрационный код:

	@RequestMapping(value = "/requestBody", method = RequestMethod.POST)
    public String requestBody(@RequestBody User user) {
        return user.toString();
    }

Обратите внимание, что для использованияPOST-запрос, для Content-Type отправителя установлено значение application/json, а данные представляют собой строку json.:

Некоторым людям даже нравится использовать Карту для получения:

ноНе используйте Map для получения, иначе код будет сложно поддерживать, старший брат может не понять, какие данные в вашей карте, поэтому лучше определить объект POJO.

В-четвертых, преобразование типа параметра

На самом деле в самом фреймворке SpringMVC есть много встроенных преобразователей типов, например, если вы передаете строковый номер, полученный входной параметр устанавливается в значение int или long, и он автоматически преобразует его для вас.

просто в сумкеorg.springframework.core.convert.converterниже, как показано на рисунке:

Иногда, если встроенного преобразователя типов недостаточно для удовлетворения потребностей бизнеса, как его расширить, это очень просто, смотрите у меня. Что такое технический бафф Java (тактический запасной вариант).

Во первых примеры.Встроенный конвертер реализует интерфейс Converter.Также реализую:

public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //String转换成Date类型
            return sdf.parse(source);
        } catch (Exception e) {
            //类型转换错误
            e.printStackTrace();
        }
        return null;
    }
}

Затем зарегистрируйте преобразователь в контейнере Spring:

@Configuration
public class ConverterConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addFormatters(FormatterRegistry registry) {
        //添加类型转换器
        registry.addConverter(new StringToDateConverter());
    }
}

Тогда посмотрите на тест, все строки даты автоматически преобразуются в тип Date, что очень удобно:

Пять, прыжок страницы

До того, как интерфейс и сервер разделены, работа по переходу страниц контролируется серверной частью, а для отображения данных используется JSP. Хотя JSP сейчас почти не используется в интернет-проектах, я думаю, что его все же нужно изучить, потому что некоторые старые проекты все еще используют JSP или нуждаются в рефакторинге.

Если вы напрямую возвращаете строку в методе RequestMapping, она не будет переходить на указанную страницу JSP, вам нужно выполнить некоторую настройку.

Первый шаг — добавить конфигурацию Maven, которая анализирует файл jsp.

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>7.0.59</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>

Второй шаг — добавить преобразователь представления.

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewClass(JstlView.class);
        return viewResolver;
    }
}

Третий шаг — установить конфигурацию IDEA.

Четвертый шаг — создать страницу jsp.

Пятый шаг, создайте контроллер Controller.

@Controller
@RequestMapping("/view")
public class ViewController {
    @RequestMapping("/hello")
    public String hello() throws Exception {
        return "hello";
    }
}

Это сделано, запускаем проект, заходим в /view/hello и видим:

Это так просто, верно?

6. @ResponseBody

Если front-end и back-end разделены, переход на страницу не требует управления back-end, а back-end нужно только возвращать json.Как вернуться?

Просто используйте аннотацию @ResponseBody, которая автоматически преобразует объект в данные json и вернет их.

Аннотация @ResponseBody может быть помещена в класс или метод.Исходный код выглядит следующим образом:

//用在类、方法上
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}

Показывать:

@RequestMapping("/userList")
@ResponseBody
public List<User> userList() throws Exception {
    List<User> list = new ArrayList<>();
    list.add(new User("1","姚大秋",18));
    list.add(new User("2","李星星",18));
    list.add(new User("3","冬敏",18));
    return list;
}

Тест /просмотр/userList:

Семь, @ModelAttribute

Существует множество вариантов использования @ModelAttribute, которые объясняются ниже.

7.1 Использование методов без возвращаемого значения

В классе Controller методы, аннотированные @ModelAttribute, выполняются до выполнения всех методов RequestMapping.

@Controller
@RequestMapping("/modelAttribute")
public class ModelAttributeController {
	//先执行这个方法
    @ModelAttribute
    public void modelAttribute(Model model){
        //在request域中放入数据
        model.addAttribute("userName","公众号:java技术爱好者");
    }

    @RequestMapping("/index")
    public String index(){
        //跳转到inex.jsp页面
        return "index";
    }
}

Страница index.jsp выглядит следующим образом:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<!-- 获取到userName属性值 -->
<h1>${userName}</h1>
</body>
</html>

Аннотированный метод @ModelAttribute, эквивалентный перехватчику Controller, выполняется до выполнения метода RequestMapping. Поэтому используйте его с осторожностью.

Запустите проект и посетите /modelAttribute/index, чтобы увидеть:

Даже если значение атрибута userName не помещено в метод index(), страница jsp может получить его, поскольку метод modelAttribute() был введен до выполнения метода index().

7.2 О методе с возвращаемым значением

На самом деле порядок вызова такой же, и он тоже выполняется перед методом RequestMapping, разница только в том, что возвращаемое значение метода прямо за вас помещается в поле Request.

//放在有参数的方法上
@ModelAttribute
public User userAttribute() {
    //相当于model.addAttribute("user",new User("1", "Java技术爱好者", 18));
    return new User("1", "Java技术爱好者", 18);
}

@RequestMapping("/user")
public String user() {
    return "user";
}

Создайте user.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<h1>ID:${user.id}</h1>
<h1>名称:${user.name}</h1>
<h1>年龄:${user.age}岁</h1>
</body>
</html>

есть тест:

Значение атрибута, помещенное в поле «Запрос», по умолчанию соответствует строчной верблюжьей букве первой буквы имени класса. Что, если вы хотите настроить его? Это так просто:

//自定义属性名为"u"
@ModelAttribute("u")
public User userAttribute() {
    return new User("1", "Java技术爱好者", 18);
}
/**
JSP就要改成这样写:
<h1>ID:${u.id}</h1>
<h1>名称:${u.name}</h1>
<h1>年龄:${u.age}岁</h1>
*/

7.3 О методе RequestMapping

@Controller
@RequestMapping("/modelAttribute")
public class ModelAttributeController {
    
    @RequestMapping("/jojo")
    @ModelAttribute("attributeName")
    public String jojo() {
        return "JOJO!我不做人了!";
    }
}

В этом случае значение, возвращаемое методом RequestMapping, не является представлением JSP. Вместо этого поместите возвращаемое значение в значение атрибута в поле Запрос, имя атрибута — attributeName. Представление — это URL-адрес в аннотации RequestMapping, поэтому создайте соответствующую страницу JSP:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<h1>${attributeName}</h1>
</body>
</html>

есть тест:

7.4 Ввод входных параметров метода

Помещение его во входной параметр означает, что соответствующее значение атрибута извлекается из предыдущей Модели и используется в качестве входного параметра. Следующим образом:

@ModelAttribute("u")
public User userAttribute() {
    return new User("1", "Java技术爱好者", 18);
}

@RequestMapping("/java")
public String user1(@ModelAttribute("u") User user) {
    //拿到@ModelAttribute("u")方法返回的值,打印出来
    System.out.println("user:" + user);
    return "java";
}

есть тест:

Восемь, перехватчик

Перехватчики являются ключевым содержимым, и часто используются перехватчики, такие как проверка входа в систему, проверка разрешений и т. д. Как SpringMVC добавляет перехватчики?

Очень просто, реализуйте интерфейс HandlerInterceptor, а в интерфейсе есть три метода, которые нужно переписать.

  • preHandle(): вызывается до того, как обработчик службы обработает запрос. предварительная обработка.
  • postHandle(): выполняется после того, как бизнес-процессор завершил обработку запроса и перед созданием представления. Постобработка.
  • afterCompletion(): вызывается после того, как DispatcherServlet полностью обработает запрос и может использоваться для очистки ресурсов и т. д. обработка возврата (страница отрендерилась);

Пользовательский перехватчик, реализованный интерфейс HandlerInterceptor:

public class DemoInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //预处理,返回true则继续执行。如果需要登录校验,校验不通过返回false即可,通过则返回true。
        System.out.println("执行preHandle()方法");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //后处理
        System.out.println("执行postHandle()方法");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //在DispatcherServlet完全处理完请求后被调用
        System.out.println("执行afterCompletion()方法");
    }
}

Затем добавьте перехватчик в контейнер Spring:

@Configuration
public class ConverterConfig extends WebMvcConfigurationSupport {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/**");
    }
}

/** представляет все пути, проверьте это:

9. Глобальная обработка исключений

SpringMVC сам обрабатывает некоторые исключения глобально, поэтому есть встроенный обработчик исключений, где он?

СмотретьHandlerExceptionResolverДиаграмма классов интерфейса знает:

Из диаграммы классов видно, что обработчиков исключений четыре:

  • DefaultHandlerExceptionResolver, обработчик исключений по умолчанию. В соответствии с каждым типом исключения возвращаются разные виды исключений.
  • SimpleMappingExceptionResolver, простой обработчик исключений сопоставления. Исключение разрешается путем настройки отношения между классом исключения и представлением.
  • ResponseStatusExceptionResolver, обработчик исключений кода состояния. разбор с@ResponseStatusИсключение типа аннотации.
  • ExceptionHandlerExceptionResolver, обработчик исключений в виде аннотаций. правильно@ExceptionHandlerАннотированные методы выполняют разбор исключений.

Первый обработчик исключений по умолчанию — это встроенный обработчик исключений, который обычно игнорируется при обработке некоторых общих исключений. Последние три требуют внимания и используются для расширения.

9.1 SimpleMappingExceptionResolver

Перевод просто отображает обработчики исключений. Польза в том, что мы можемУкажите исключение и перейдите на указанную страницу после создания этого исключения. Пожалуйста, посмотрите демо.

Первым делом нужно добавить файл spring-config.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.xsd">
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 定义默认的异常处理页面 -->
        <property name="defaultErrorView" value="err"/>
        <!-- 定义异常处理页面用来获取异常信息的属性名,默认名为exception -->
        <property name="exceptionAttribute" value="ex"/>
        <!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常也页名作为值 -->
        <property name="exceptionMappings">
            <props>
                <!-- 异常,err表示err.jsp页面 -->
                <prop key="java.lang.Exception">err</prop>
                <!-- 可配置多个prop -->
            </props>
        </property>
    </bean>
</beans>

Второй шаг — загрузить файл xml в класс запуска:

@SpringBootApplication
@ImportResource("classpath:spring-config.xml")
public class SpringmvcApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringmvcApplication.class, args);
    }

}

Третий шаг — создать страницу err.jsp в каталоге webapp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>异常页面</title>
</head>
<body>
<h1>出现异常,这是一张500页面</h1>
<br>
<%-- 打印异常到页面上 --%>
<% Exception ex = (Exception)request.getAttribute("ex"); %>
<br>
<div><%=ex.getMessage()%></div>
<% ex.printStackTrace(new java.io.PrintWriter(out)); %>
</body>
</html>

Это сделано, напишите интерфейс для проверки:

@Controller
@RequestMapping("/exception")
public class ExceptionController {
    @RequestMapping("/index")
    public String index(String msg) throws Exception {
        if ("null".equals(msg)) {
            //抛出空指针异常
            throw new NullPointerException();
        }
        return "index";
    }
}

Эффект следующий:

Этот тип обработчика исключений почти невидим в проекте, где интерфейс и сервер теперь разделены.

9.2 ResponseStatusExceptionResolver

Этот обработчик исключений в основном используется для обработки@ResponseStatusАннотированное исключение. См. демо-код:

Настройте класс исключений и используйте@ResponseStatusМодификация аннотации:

//HttpStatus枚举有所有的状态码,这里返回一个400的响应码
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class DefinedException extends Exception{
}

Напишите интерфейс контроллера для тестирования:

@RequestMapping("/defined")
public String defined(String msg) throws Exception {
    if ("defined".equals(msg)) {
        throw new DefinedException();
    }
    return "index";
}

Запустите проект и протестируйте его, эффект следующий:

9.3 ExceptionHandlerExceptionResolver

Аннотированные обработчики исключений, которые используются чаще всего. Он очень прост и удобен в использовании.

Первым шагом является определение пользовательского исключения BaseException:

public class BaseException extends Exception {
    public BaseException(String message) {
        super(message);
    }
}

Второй шаг — определить класс сущностей подсказки об ошибке ErrorInfo:

public class ErrorInfo {
    public static final Integer OK = 0;
    public static final Integer ERROR = -1;
    private Integer code;
    private String message;
    private String url;
    //getter、setter
}

Третий шаг — определить глобальный класс обработки исключений GlobalExceptionHandler:

//这里使用了RestControllerAdvice,是@ResponseBody和@ControllerAdvice的结合
//会把实体类转成JSON格式的提示返回,符合前后端分离的架构
@RestControllerAdvice
public class GlobalExceptionHandler {

    //这里自定义了一个BaseException,当抛出BaseException异常就会被此方法处理
    @ExceptionHandler(BaseException.class)
    public ErrorInfo errorHandler(HttpServletRequest req, BaseException e) throws Exception {
        ErrorInfo r = new ErrorInfo();
        r.setMessage(e.getMessage());
        r.setCode(ErrorInfo.ERROR);
        r.setUrl(req.getRequestURL().toString());
        return r;
    }
}

После этого напишите тестовый интерфейс:

@RequestMapping("/base")
public String base(String msg) throws Exception {
    if ("base".equals(msg)) {
        throw new BaseException("测试抛出BaseException异常,欧耶!");
    }
    return "index";
}

Запустите проект и протестируйте:

болтовня

Функций SpringMVC определенно больше, чем я написал, но, изучив вышеизложенное, вы в принципе сможете заниматься повседневной работой.

Если вы хотите углубиться, лучше всего посмотреть исходный код SpringMVC, я уже написал три статьи,Шаблон цепочки ответственности и перехватчик SpringMVC, шаблон адаптера и SpringMVC, анализ исходного кода глобальной обработки исключений. Если вам интересно, вы можете подписаться на официальный аккаунт, чтобы увидеть мои исторические статьи.

Публичный аккаунт WeChat был открыт: [энтузиаст технологии Java], студенты, которые не обращали внимания, не забудьте обратить внимание~

Придерживайтесь оригинальности и продолжайте публиковать технические статьи как с широтой, так и с глубиной.

Статья была включена в мою подборку на Github, добро пожаловать в Star:GitHub.com/Yehongqin/Лай…

Код для всех приведенных выше примеров был загружен на Github:

GitHub.com/yehongqin/no…

Ставьте лайки, если считаете это полезным, ваши лайки — самая большая мотивация для моего творчества.~

Не хочу быть соленой рыбой, я программист, стремящийся запомниться всем. Увидимся в следующий раз! ! !

Возможности ограничены, если есть какие-то ошибки или неуместности, пожалуйста, критикуйте и исправьте их, учитесь и общайтесь вместе!