Spring 全局请求处理:根据请求类型返回 JSON 或 HTML
在现代 Web 应用开发中,前后端分离的架构越来越普遍。为了更好地支持这种架构,Spring 框架提供了强大的功能来处理不同类型的请求,并根据请求的类型返回相应的响应格式,如 JSON 或 HTML。本文将介绍如何使用 Spring 的全局请求处理机制,根据请求类型动态返回 JSON 或 HTML 响应。
1. 配置 Thymeleaf 模板引擎
首先,我们需要配置 Thymeleaf 模板引擎,以便在需要时返回 HTML 页面。以下是 Thymeleaf 的基本配置:
spring:
thymeleaf:
cache: false # 关闭缓存以方便开发
mode: HTML5 # 使用 HTML5 模式
encoding: UTF-8 # 设置字符编码
prefix: classpath:/templates/ # 设置模板文件的前缀路径
2. 判断请求是否为 AJAX 请求
在处理请求时,我们需要判断请求是否为 AJAX 请求。如果是 AJAX 请求,我们通常希望返回 JSON 格式的数据;否则,返回 HTML 页面。以下是一个简单的判断方法:
public static boolean isAjaxRequest(HttpServletRequest request) {
// 检查请求头中是否包含 "x-requested-with",通常 AJAX 请求会包含此头信息
return request.getHeader("x-requested-with") != null;
}
3. 全局异常处理
为了统一处理应用中的异常,我们可以使用 @ControllerAdvice
注解来定义一个全局异常处理器。该处理器会根据请求类型返回不同的响应格式。
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
/**
* 全局异常处理器
*/
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
private static final String ERROR_PAGE = "error"; // 错误页面名称
/**
* 处理全局异常
* @param httpServletRequest 请求对象
* @param httpServletResponse 响应对象
* @param e 异常对象
* @return 根据请求类型返回 JSON 或 HTML 响应
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Object handleException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Exception e) throws UnsupportedEncodingException {
if (isAjaxRequest(httpServletRequest)) {
// 如果是 AJAX 请求,返回 JSON 格式的错误信息
return json(e);
}
// 否则返回 HTML 错误页面
return view(e);
}
/**
* 返回 JSON 格式的错误信息
* @param e 异常对象
* @return 自定义的响应对象
*/
private ResponseX json(Exception e) {
return new ResponseX(); // 这里返回项目中自定义的统一响应对象即可
}
/**
* 返回 HTML 错误页面
* @param e 异常对象
* @return ModelAndView 对象
*/
public ModelAndView view(Exception e) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setStatus(HttpStatus.BAD_REQUEST); // 设置响应状态码
modelAndView.setViewName(ERROR_PAGE); // 设置视图名称
modelAndView.addObject("msg", "错误信息"); // 添加错误信息
modelAndView.addObject("code", "错误代码"); // 添加错误代码
return modelAndView;
}
}
4. 错误页面模板
当异常处理器返回 HTML 页面时,我们需要定义一个错误页面模板。以下是一个简单的 Thymeleaf 模板示例:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<head th:insert="fragments/header"/>
<title>错误页面</title>
</head>
<body>
<span th:text="${code}"></span> - <span th:text="${msg}"></span>
</body>
</html>
5. 避免使用拦截器处理异常
虽然拦截器在处理请求时非常有用,但它并不适合处理 Controller 中的异常。拦截器主要用于处理请求的前后逻辑,而异常处理通常需要在 Controller 层进行。以下是 Spring 中 DispatcherServlet
处理异常的代码片段:
private void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, Exception ex) throws Exception {
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, ex);
}
throw ex; // 抛出异常,由异常处理器处理
}
通过使用 Spring 的 @ControllerAdvice
注解和 Thymeleaf 模板引擎,我们可以轻松地实现根据请求类型返回 JSON 或 HTML 响应的功能。这种机制不仅提高了代码的可维护性,还使得应用能够更好地适应前后端分离的架构。希望本文能帮助你在实际项目中更好地处理全局请求和异常。
版权声明:本文为原创文章,版权归 全栈开发技术博客 所有。
本文链接:https://www.lvtao.net/dev/spring-ControllerAdvice-json-html.html
转载时须注明出处及本声明