SpringBoot 2.x (5):异常处理与部署WAR项目

异常处理:

SpringBoot的异常处理是不友好的,前端只会显示最基本的错误名称

后端控制台会报出具体的错误,那么我们如何告知前端具体的错误信息呢?

 

1:对全局异常进行处理

一个测试的Controller:

package org.dreamtech.springboot.exception;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExceptionController {
    @RequestMapping("/test/exception")
    private Object test() {
        int i = 1 / 0;
        return "test";
    }
}

 

自定义一个异常处理类:

package org.dreamtech.springboot.exception;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
//类似的,有@ControllerAdvice
public class CustomExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    Object handleException(Exception e, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", 100);
        map.put("errMsg", e.toString());
        map.put("url", request.getRequestURI());
        return map;
    }
}

更进一步,可以加入日志处理:

package org.dreamtech.springboot.exception;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class CustomExceptionHandler {

    private static final Logger LOG = LoggerFactory.getLogger(CustomExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    Object handleException(Exception e, HttpServletRequest request) {
        LOG.error("url {},msg {}", request.getRequestURI(), e.toString());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", 100);
        map.put("errMsg", e.toString());
        map.put("url", request.getRequestURI());
        return map;
    }
}

 

如果前端访问了测试URL,应该显示的内容是:

{"code":100,"errMsg":"java.lang.ArithmeticException: / by zero","url":"/test/exception"}

 

2.自定义异常处理

导入SpringBoot推荐的thymeleaf模板引擎:

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

 

新建自定义异常类:

package org.dreamtech.springboot.exception;

public class MyException extends RuntimeException {

    private static final long serialVersionUID = -1876094492594770999L;

    public MyException(String code, String msg) {
        super();
        this.code = code;
        this.msg = msg;
    }

    private String code;
    private String msg;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

 

测试Controller:

package org.dreamtech.springboot.exception;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExceptionController {
    @RequestMapping("/test/exception")
    private Object test() {
        throw new MyException("101", "error");
    }
}

 

异常处理类:

package org.dreamtech.springboot.exception;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(value = MyException.class)
    Object handleException(MyException e, HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error.html");
        modelAndView.addObject("msg", e.toString());
        System.out.println(e.toString());
        return modelAndView;
    }
}

 

可以看出,我这里是返回了一个错误页面:error.html,当然也可以返回JSON,类似上面的@RestControllerAdvice

巧合的是,我运行SpringBoot之后发现所有错误页面都跳转到error.html,一开始以为是配置错误了

后来仔细测试后发现,SpringBoot默认将error.html作为同意异常处理页面了,哈哈

 

 部署WAR项目:

通常情况下,我们都会将SpringBoot项目打包成JAR包,然后java -jar启动

然而,有些特殊情况下,我们不得不使用老方式打包成WAR然后部署Tomcat

 

无论打包成JAR还是WAR都需要MAVEN插件:通常自动生产的项目是自带的

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

 

如果要打包成WAR,首先需要定义打包方式为WAR:

    <packaging>war</packaging>

 

然后在BUILD中加入项目名称:

    <build>
        <finalName>demo</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

 

下载Tomcat,针对SpringBoot2.x推荐Tomcat9以上版本

https://tomcat.apache.org/download-90.cgi

 

修改启动类:

public class DemoApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(DemoApplication.class);
    }

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

}

 

然后打包即可

 

容器不只有Tomcat,还有Jetty和Undertow等等,只不过最常用的是Tomcat

针对容器的性能,可以采用Jmter进行测试

 

SpringBoot的启动流程:

 

posted @ 2019-05-06 21:39  4ra1n  阅读(708)  评论(0编辑  收藏  举报