Spring RESTful Web服务中的异常处理

1.简介

我们可能已经在Spring中遇到了几种处理RESTful Web服务应用程序中异常的方法。 在本文中,我们将尝试探索可以采取的最佳方法来实现有效的异常处理。

2.问题陈述

让我们创建一个简单的应用程序,该应用程序将在REST URI中标识员工姓名。 如果请求中提供的员工名称是数字,则让我们的应用程序引发一个自定义异常,该异常将通过Exception Handlers处理 ,并相应地将JSON响应返回给客户端。 成功响应将是带有员工详细信息的JSON,而失败响应将是带有errorCode和正确的错误消息的错误JSON。

3.实施

首先让我们检查一下pom文件条目web.xml的样子–

pom.xml

<!-- Spring dependencies -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>4.2.1.RELEASE</version>
</dependency>
 
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>4.2.1.RELEASE</version>
</dependency>
 
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.2.1.RELEASE</version>
</dependency>
 
<!-- Jackson JSON Processor -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.4.1</version>
</dependency>

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
 
	<display-name>RESTWithSpringMVCException</display-name>
 
	<servlet>
		<servlet-name>mvc-dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
 
	<servlet-mapping>
		<servlet-name>mvc-dispatcher</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
 
</web-app>

现在让我们检查一下Web应用程序上下文

mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
 
	<mvc:annotation-driven />
	
	<context:component-scan base-package="com.jcombat.controller" />
 
</beans>

现在是时候创建实体类了,一个用于Employee ,另一个用于ErrorResponse ,在我们应用程序中任何层出现任何异常的情况下,都将以JSON的形式返回。

Employee.java

package com.jcombat.bean;
 
public class Employee {
	private String empId;
	private String name;
	
	public String getEmpId() {
		return empId;
	}
	public void setEmpId(String empId) {
		this.empId = empId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

ErrorResponse.java

package com.jcombat.bean;
 
public class ErrorResponse {
	private int errorCode;
	private String message;
	
	public int getErrorCode() {
		return errorCode;
	}
	public void setErrorCode(int errorCode) {
		this.errorCode = errorCode;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
}

我们还需要拥有自己的自定义异常类。 我希望我们所有人都已经知道自定义异常。 让我们快速为我们的应用程序创建一个。

EmployeeException.java

package com.jcombat.exception;
 
public class EmployeeException extends Exception {
	private static final long serialVersionUID = 1L;
	private String errorMessage;
 
	public String getErrorMessage() {
		return errorMessage;
	}
	public EmployeeException(String errorMessage) {
		super(errorMessage);
		this.errorMessage = errorMessage;
	}
	public EmployeeException() {
		super();
	}
}

Spring为我们提供了@ExceptionHandler批注,以专门处理控制器中特定或常见类型的异常。

这里最重要的部分是为我们的应用程序编写rest控制器。

DemoController.java

package com.jcombat.controller;
 
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
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.bind.annotation.RestController;
 
import com.jcombat.bean.Employee;
import com.jcombat.bean.ErrorResponse;
import com.jcombat.exception.EmployeeException;
 
@RestController
public class EmployeeController {
 
	@RequestMapping(value = "/{firstName}", method = RequestMethod.GET)
	public ResponseEntity<Employee> showMessage(
			@PathVariable("firstName") String firstName,
			@RequestParam(value = "empId", required = false, defaultValue = "00000") final String empId) throws EmployeeException {
 
		Employee employee = new Employee();
		employee.setEmpId(empId);
		employee.setFirstName(firstName);
 
		if (StringUtils.isNumeric(firstName)) {
			throw new EmployeeException("Invalid employee name requested");
		}
 
		return new ResponseEntity<Employee>(employee, HttpStatus.OK);
	}
 
	@ExceptionHandler(EmployeeException.class)
	public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
		ErrorResponse error = new ErrorResponse();
		error.setErrorCode(HttpStatus.PRECONDITION_FAILED.value());
		error.setMessage(ex.getMessage());
		return new ResponseEntity<ErrorResponse>(error, HttpStatus.OK);
	}
}

注意控制器中的@ExceptionHandler方法,该方法仅应处理在应用程序的任何层中引发的EmployeeException

但是,如果从任何地方抛出NullPointerException怎么办。 为了安全起见,我们必须在应用程序中具有通用的异常处理程序,该处理程序可以处理所有其他异常类型,例如IOExceptionNullPointerException等。 为此,Spring在版本3.2中引入了@ControllerAdvice ,可以在我们的应用程序中创建Controller Advice类,该类将能够处理所有全局异常情况。

@ControllerAdvice注释的类将被注册为全局异常处理程序

让我们为我们的应用程序创建一个。

ExceptionControllerAdvice.java

package com.jcombat.controller;
 
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
 
import com.jcombat.bean.ErrorResponse;
 
@ControllerAdvice
public class ExceptionControllerAdvice {
 
	@ExceptionHandler(Exception.class)
	public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
		ErrorResponse error = new ErrorResponse();
		error.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
		error.setMessage("Please contact your administrator");
		return new ResponseEntity<ErrorResponse>(error, HttpStatus.OK);
	}
}

这意味着,如果我们在应用程序中遇到了除自定义异常之外的意外异常,则将准备一个通用错误对象,其中包含通用错误代码和错误消息,并将它们作为错误JSON响应返回。

在早于3.2的Spring版本中,使用单个基本控制器创建,扩展所有单个控制器而不是@ControllerAdvice会是更好的选择。

这里有一些注意事项。 由于缺少Spring 3.0.x提供的支持,在Spring 3.0.x中无法通过ResponseEntity返回错误的JSON响应。 替代方法是将BeanNameViewResolverModelAndView一起用作返回类型。 我们将很快为此提供一个示例应用程序。

4.运行应用程序

是时候运行我们创建的应用程序了。

确保我们已将应用程序发布到服务器并启动了它。

现在,在浏览器中点击下面的URI – http:// localhost:8080 / RESTWithSpringMVCException / Ramesh?empId = 1234

成功2

让我们看看错误响应的样子。 请注意,我们在EmployeeController中添加了一个IF块,该块检查雇员名字的路径变量是否为数字。 如果是数字,则我们的应用程序将抛出EmployeeException 。 让我们点击下面的URI –

失败

如果需要将电子邮件添加为路径变量之一,那么更好的方法是遍历在上一教程中创建的RESTful服务应用程序

5.下载源代码

翻译自: https://www.javacodegeeks.com/2016/01/exception-handling-spring-restful-web-service.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值