天津网站建设定制电子商务网站包括

张小明 2026/1/11 3:31:59
天津网站建设定制,电子商务网站包括,百度关键词推广方案,深圳网络推广哪家好目录 Spring Boot统一功能处理详解#xff08;新手完整版#xff09; 1. 拦截器详解 1.1 什么是拦截器 1.2 完整代码实现#xff08;逐行注释#xff09; 1.2.1 定义登录拦截器#xff08;传统Session方式#xff09; 1.2.3 定义登录拦截器#xff08;现代Token方…目录Spring Boot统一功能处理详解新手完整版1. 拦截器详解1.1 什么是拦截器1.2 完整代码实现逐行注释1.2.1 定义登录拦截器传统Session方式1.2.3 定义登录拦截器现代Token方式推荐1.3 注册拦截器到Spring MVC2. 统一数据返回格式2.1 为什么需要统一格式2.2 完整实现代码2.2.1 统一结果类Result2.2.2 全局响应处理器ResponseAdvice3. 统一异常处理3.1 为什么需要统一处理3.2 完整实现代码3.2.1 全局异常处理器3.2.2 自定义业务异常4. 完整项目结构示例5. 知识点与代码的完整对应关系表6. 新手最容易踩的坑6.1 拦截器不生效6.2 String类型异常6.3 异常没捕获7. 总结与最佳实践7.1 三者的协作流程图7.2 代码层面的最佳实践8. 进阶为什么 Spring MVC 需要适配器模式选读Spring Boot统一功能处理详解新手完整版前置准备本教程使用 Lombok 简化代码如Data,Slf4j请务必在pom.xml中添加依赖并在 IDE 中安装 Lombok 插件否则代码会报错。dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency1. 拦截器详解1.1 什么是拦截器拦截器是Spring MVC提供的安检门机制能在请求到达Controller之前、之后以及请求完成时插入自定义逻辑。它就像你去商场时要经过的安检安检前检查包裹(preHandle)安检后刷卡(postHandle)离开时记录时间(afterCompletion)。核心应用场景登录认证检查用户是否登录如未登录不能访问订单页面日志记录记录每个请求的处理时间权限控制判断用户是否有权限访问某个接口性能监控统计接口响应时间1.2 完整代码实现逐行注释1.2.1 定义登录拦截器传统Session方式⚠️ 注意Session方式适合传统Web页面项目。对于现代前后端分离项目Vue/React Spring Boot推荐使用JWT Token方案见1.2.3节。// import关键字导入其他包中的类就像你要用别人的工具得先拿来 // slf4jSimple Logging Facade for Java日志门面框架类似一个日志的翻译官 // 它能让你在不改代码的情况下切换log4j、logback等具体实现 import lombok.extern.slf4j.Slf4j; // Spring框架的组件注解标记这个类为Spring管理的Bean就像商品贴上条形码入库 // Spring容器会自动创建它的实例其他地方可以直接借用 import org.springframework.stereotype.Component; // Spring MVC的核心接口实现它就拥有了拦截请求的能力 // 类似安检员资格证只有拿到这个证才能在指定位置检查 import org.springframework.web.servlet.HandlerInterceptor; // Servlet规范提供的HTTP请求对象封装了客户端发送的所有信息 // 包括请求头、参数、Cookie等相当于快递包裹单 import jakarta.servlet.http.HttpServletRequest; // Servlet规范提供的HTTP响应对象用于向客户端返回数据 // 相当于快递回执单你可以填写返回内容和状态 import jakarta.servlet.http.HttpServletResponse; // Session是会话对象用于在多次请求间保存用户状态 // 就像商场的储物柜存一次东西多次取前提是有钥匙 import jakarta.servlet.http.HttpSession; /** * 登录拦截器Session版 * Slf4jLombok注解自动生成日志记录器 * Component让Spring管理这个拦截器 */ Slf4j Component public class LoginInterceptor implements HandlerInterceptor { /** * preHandle在Controller方法执行前调用安检门第一道关卡 * 返回true 放行绿灯返回false 拦截红灯 * * param request HTTP请求对象包裹单 * param response HTTP响应对象回执单 * param handler 要执行的Controller方法目标商店 * return boolean 是否允许通过 */ Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info(LoginInterceptor.preHandle() - 开始检查用户登录状态, URI: {}, request.getRequestURI()); // 获取Session参数false表示没有就别新建 HttpSession session request.getSession(false); // 检查Session是否存在且包含用户信息 // 是短路与左边为false右边不执行避免空指针 if (session ! null session.getAttribute(user) ! null) { log.info(用户已登录放行请求); return true; // 放行 } // 没登录设置401状态码Unauthorized未授权 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // SC_UNAUTHORIZED就是401的常量 log.warn(用户未登录请求被拦截); return false; // 拦截不执行后续操作 } // ... postHandle和afterCompletion方法同上省略 ... }1.2.3 定义登录拦截器现代Token方式推荐import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; /** * 登录拦截器JWT Token版 - 前后端分离项目推荐 * 从请求头中获取Token进行验证 */ Slf4j Component public class TokenInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info(TokenInterceptor.preHandle() - 开始验证Token, URI: {}, request.getRequestURI()); // 从请求头中获取Token前端在Header中传递Authorization: Bearer xxxx String token request.getHeader(Authorization); // 简单的Token验证逻辑实际应调用JWT工具类解析 if (token ! null token.startsWith(Bearer ) validateToken(token)) { log.info(Token验证通过放行请求); return true; } // Token无效或过期 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); log.warn(Token验证失败请求被拦截); return false; } /** * 模拟Token验证方法实际应使用JWT库解析 * param token 请求头中的Token字符串 * return 是否有效 */ private boolean validateToken(String token) { // 实际业务解析JWT验证签名是否有效、是否过期 // 例如return JwtUtil.verify(token.replace(Bearer , )); return Bearer valid-token.equals(token); // 模拟实现 } }1.3 注册拦截器到Spring MVC// ... import 语句略 ... Configuration public class WebConfig implements WebMvcConfigurer { Autowired private LoginInterceptor loginInterceptor; // 或 TokenInterceptor // 定义不需要拦截的路径列表 private ListString excludePaths Arrays.asList( /user/login, // 登录接口 /user/register, // 注册接口 /api/auth/refresh, // Token刷新接口Token方式需要 /static/**, // 静态资源 /error/** // 错误页面 ); Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) // 或 tokenInterceptor .addPathPatterns(/**) // 先全部拦截 .excludePathPatterns(excludePaths); // 再开放白名单 log.info(拦截器注册完成已应用登录验证); } }2. 统一数据返回格式2.1 为什么需要统一格式想象你是前端开发后端同事张三返回{name:张三}李四返回李四王五返回true。你要写三种不同的解析逻辑维护成本极高统一格式后所有接口都返回{ status: 200, data: 实际数据, errorMessage: , timestamp: 1234567890 }前端只需写一套解析逻辑取data字段即可。2.2 完整实现代码2.2.1 统一结果类Resultimport lombok.Data; /** * 统一返回结果类 * param T 泛型表示data字段可以是任何类型 */ Data public class ResultT { private int status; private String errorMessage; private T data; private long timestamp; private Result() { this.timestamp System.currentTimeMillis(); } public static T ResultT success(T data) { ResultT result new Result(); result.setStatus(200); result.setData(data); return result; } public static T ResultT fail(String errorMessage) { ResultT result new Result(); result.setStatus(500); result.setErrorMessage(errorMessage); return result; } public static T ResultT custom(int status, String errorMessage, T data) { ResultT result new Result(); result.setStatus(status); result.setErrorMessage(errorMessage); result.setData(data); return result; } }2.2.2 全局响应处理器ResponseAdvice// ... import 语句略 ... Slf4j ControllerAdvice public class ResponseAdvice implements ResponseBodyAdviceObject { // Jackson转换器处理String类型专用 private static ObjectMapper mapper new ObjectMapper(); Override public boolean supports(MethodParameter returnType, Class converterType) { return true; // 处理所有返回值 } SneakyThrows Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 1. 如果已经是Result类型直接返回避免重复包装 if (body instanceof Result) { return body; } // 2. ❗❗❗ String类型特殊处理重要易错点 // Spring的StringHttpMessageConverter只接受String不接受对象 // 必须先将Result转为JSON字符串否则会报类型转换异常 if (body instanceof String) { return mapper.writeValueAsString(Result.success(body)); } // 3. 其他类型正常包装 return Result.success(body); } }3. 统一异常处理3.1 为什么需要统一处理⚠️ 反模式警告以下代码仅供对比理解实际开发中严禁在每个接口里写 try-catch// ❌ 错误示范重复代码维护噩梦不要这样做 GetMapping(/user/{id}) public ResultUser getUser(PathVariable Long id) { try { // 业务逻辑 User user userService.findById(id); return Result.success(user); } catch (Exception e) { log.error(错误, e); return Result.fail(系统错误); // 每个接口都要重复 } }统一异常处理就像一个中央错误处理中心所有未捕获的异常都汇集到这里处理Controller层只需专注业务逻辑。3.2 完整实现代码3.2.1 全局异常处理器Slf4j ResponseBody ControllerAdvice public class ErrorAdvice { /** * 兜底处理器处理所有未被捕获的异常 */ ExceptionHandler(Exception.class) ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ResultObject handleGeneralException(Exception e) { log.error(系统发生未处理异常: {}, e.getMessage(), e); return Result.fail(系统繁忙请稍后再试); } /** * 处理业务异常自定义异常 */ ExceptionHandler(BusinessException.class) ResponseStatus(HttpStatus.BAD_REQUEST) public ResultObject handleBusinessException(BusinessException e) { log.warn(业务异常[错误码:{}]: {}, e.getErrorCode(), e.getMessage()); return Result.custom(e.getErrorCode(), e.getMessage(), null); } /** * 处理参数校验异常 */ ExceptionHandler(IllegalArgumentException.class) ResponseStatus(HttpStatus.BAD_REQUEST) public ResultObject handleIllegalArgumentException(IllegalArgumentException e) { log.warn(参数错误: {}, e.getMessage()); return Result.fail(参数错误: e.getMessage()); } }3.2.2 自定义业务异常/** * 业务异常基类自定义异常 */ public class BusinessException extends RuntimeException { private int errorCode; public BusinessException(int errorCode, String message) { super(message); this.errorCode errorCode; } public int getErrorCode() { return errorCode; } } /** * 资源未找到异常 */ public class ResourceNotFoundException extends BusinessException { public ResourceNotFoundException(String resourceName, Object id) { super(404, String.format(%s[id%s]不存在, resourceName, id)); } }4. 完整项目结构示例src/main/java/com/example/demo/ ├── DemoApplication.java // 启动类 ├── config/ │ ├── WebConfig.java // 拦截器注册 │ └── ResponseAdvice.java // 统一返回 ├── controller/ │ ├── UserController.java // 用户接口 │ └── BookController.java // 图书接口 ├── interceptor/ │ └── LoginInterceptor.java // 登录拦截或TokenInterceptor ├── exception/ │ ├── ErrorAdvice.java // 统一异常 │ └── BusinessException.java // 业务异常 ├── model/ │ ├── Result.java // 统一结果 │ └── User.java // 用户实体 └── constant/ └── Constants.java // 常量类5. 知识点与代码的完整对应关系表知识点结论代码体现位置代码如何体现拦截器执行顺序preHandle→Controller→postHandle→afterCompletionDispatcherServlet.doDispatch()源码方法按顺序调用applyPreHandle()在ha.handle()之前applyPostHandle()在之后统一返回包装所有返回值变成ResultResponseAdvice.beforeBodyWrite()通过instanceof判断类型调用Result.success()包装String类型问题String需特殊处理防止转换异常if (body instanceof String)分支主动调用ObjectMapper.writeValueAsString()转为JSON字符串适配StringHttpMessageConverter异常处理优先级子类异常优先匹配ExceptionHandler的顺序Spring通过ExceptionDepthComparator比较异常继承深度深度小的优先开闭原则对扩展开放对修改关闭新增XxxHandlerAdapter类添加新Controller类型时只需新增适配器类无需修改DispatcherServlet源码6. 新手最容易踩的坑6.1 拦截器不生效问题LoginInterceptor写了但没效果。原因没实现WebMvcConfigurer或没加Configuration。代码检查点确认WebConfig类上有Configuration且实现了WebMvcConfigurer。6.2 String类型异常问题返回String时报错ClassCastException。原因没做instanceof String判断。代码检查点确认ResponseAdvice中有if (body instanceof String)分支。6.3 异常没捕获问题抛了异常但返回500错误。原因ControllerAdvice没扫描到或异常类型不匹配。代码检查点确认ErrorAdvice在Spring Boot主启动类的同级或子包下。7. 总结与最佳实践7.1 三者的协作流程图用户请求 ↓ LoginInterceptor.preHandle() (登录检查/Token验证) ↓ (放行) Controller执行业务专注业务不try-catch ↓ (抛BusinessException) ErrorAdvice捕获异常 → 返回Result.fail() ↓ (正常返回对象) ResponseAdvice.beforeBodyWrite() → 包装成Result.success() ↓ 返回给前端统一格式 {status, data, errorMessage, timestamp}7.2 代码层面的最佳实践// ✅ Controller层保持简洁只关注业务 RestController RequestMapping(/api/user) public class UserController { GetMapping(/{id}) public User getUser(PathVariable Long id) { // 直接返回User不包Result // 参数校验不通过就抛IllegalArgumentException if(id 0) throw new IllegalArgumentException(ID无效); // Service层可能抛BusinessException User user userService.getById(id); // 直接返回数据由ResponseAdvice统一包装 return user; } }最佳实践总结Controller层不手动包装Result专注业务逻辑异常直接抛Service层抛出自定义BusinessException代码语义清晰全局层ResponseAdvice和ErrorAdvice做统一处理代码复用性高8. 进阶为什么 Spring MVC 需要适配器模式选读本小节为设计原理探讨不影响实战开发可跳过在Spring MVC底层DispatcherServlet需要处理多种类型的Controller如老式Controller接口、注解Controller、HttpRequestHandler等。如果没有适配器模式DispatcherServlet会充满if-else判断// ❌ 假设没有适配器模式的噩梦代码 public void doDispatch(HttpServletRequest request, HttpServletResponse response) { Object handler getHandler(request); if (handler instanceof Controller) { ((Controller) handler).handleRequest(request, response); } else if (handler instanceof HttpRequestHandler) { ((HttpRequestHandler) handler).handleRequest(request, response); } else if (handler.getClass().isAnnotationPresent(Controller.class)) { // 复杂的反射调用逻辑... } // 每新增一种Controller类型都要修改这段代码 }适配器模式解决方案HandlerAdapter接口统一了调用方式supports()handle()DispatcherServlet只需调用adapter.handle()无需关心具体类型新增Controller类型时只需新增一个适配器类无需修改DispatcherServlet源码结论适配器模式的本质是将调用的复杂性从调用者DispatcherServlet转移到适配器HandlerAdapter中让核心逻辑保持稳定符合开闭原则对扩展开放对修改关闭。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

东莞纸箱定制 技术支持 东莞网站建设个人备案经营网站

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

张小明 2026/1/10 6:54:46 网站建设

网站开发路径百度账号怎么改用户名

模型压缩技术实战:TensorFlow模型剪枝与量化 在智能手机上运行图像识别、在智能手表中实现语音唤醒、让摄像头实时检测异常行为——这些看似平常的功能背后,往往依赖着复杂的深度学习模型。然而,原始的神经网络动辄数百兆大小、需要高性能GPU…

张小明 2026/1/10 6:54:48 网站建设

做网站需要多钱温州网站开发建设

为什么这款音乐播放器能让你告别版权限制的烦恼 【免费下载链接】NeteaseMusic NeteaseMusic: 这是一个第三方的Web端音乐播放器,结合了网易云音乐和QQ音乐的资源,允许用户在线播放、搜索歌曲、获取歌词和评论等。 项目地址: https://gitcode.com/gh_m…

张小明 2026/1/10 6:54:51 网站建设

丰台建设企业网站seo外链推广平台

第一章:自动化测试工具的演进与行业需求随着软件开发模式从传统的瀑布模型转向敏捷和DevOps,自动化测试工具经历了显著的演进。早期的测试主要依赖手动执行,效率低且容易遗漏边界情况。为应对快速迭代的需求,行业逐步引入脚本化测…

张小明 2026/1/10 6:54:47 网站建设

深圳外贸建站网络推广公司如何评价一个网页的设计

新能源电池盖板表面氧化层影响焊接密封性。研洁等离子清洗设备可温和去除氧化层并提升表面活性,焊接缺陷率显著下降,满足自动化产线高节拍需求。电池盖板多为铝合金,表面自然氧化膜降低激光焊接润湿性,易出现气孔、裂纹&#xff0…

张小明 2026/1/10 6:54:47 网站建设

网站网站开发逻辑乐陵seo优化推广

在数字工作环境中,快捷键已成为提升效率的必备工具。然而当CtrlS保存文档时毫无反应,或是AltTab切换窗口时遭遇卡顿,这些令人沮丧的时刻往往源于快捷键冲突。Hotkey Detective作为专业的快捷键侦探,能够精准定位并解决这些隐藏的系…

张小明 2026/1/10 5:06:05 网站建设