Java生鲜电商平台-异常模块的设计与架构

说明:任何一个软件系统都会出现各式各样的异常与错误,我们需要根据异常的情况进行捕获与分析,改善自己的代码,让其更加的稳定的,快速的运行,那么作为一个

B2B的Java开源生鲜电商平台,我们的异常需要思考以下几个维度。

1. 运行的代码异常

    说明:代码在运行的过程中,难免出现各种异常与错误,我们采用Log4j进行日志的记录。

              在分层代码解耦过程中,我们统一在Controller进行异常的捕获与日志记录。

相关的运行的代码异常架构如下:

  1. /**
  2. * (商家店铺)商品信息列表
  3. * @param request
  4. * @param response
  5. * @return
  6. */
  7. @RequestMapping(value = "/goods/list", method = { RequestMethod.GET})
  8. public JsonResult goodsList(HttpServletRequest request, HttpServletResponse response) {
  9. try
  10. {
  11. //业务逻辑处理
  12. return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试","");
  13. }catch(Exception ex){
  14. logger.error("[GoodsController][goodsList] exception :",ex);
  15. return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试","");
  16. }
  17. }

说明:由于spring的事物控制在service层,所以service层不抓取异常。所有的异常都在controller进行抓取,而且抓取的是任何的异常

           异常的记录采用某个类[]某个方法[] exception,这种方式,然后把所有的异常的堆栈信息进行打印出来,方便进行查看与分析,定位等

2. 全局异常

     说明:对于有可能出现的全局异常,我们采用Spring的全局异常处理器,进行代码的统一处理。 

   2.1,对于业务层的异常,我们采用自定义异常进行获取

  核心代码如下:

  1. /**
  2. * service异常,业务异常继续于当前接口
  3. *
  4. */
  5. public class ServiceException extends RuntimeException {
  6.  
  7. private static final long serialVersionUID = 4875141928739446984L;
  8.  
  9. /**
  10. * 错误码
  11. */
  12. protected String code;
  13.  
  14. /**
  15. * 错误信息
  16. */
  17. protected String message;
  18.  
  19. public ServiceException(String code, String message) {
  20. super();
  21. this.code = code;
  22. this.message = message;
  23. }
  24.  
  25. public ServiceException(String code, String message, Throwable t) {
  26. super();
  27. this.code = code;
  28. this.message = message;
  29. }
  30.  
  31. public ServiceException(String message) {
  32. super(message);
  33. this.message = message;
  34. }
  35.  
  36. public ServiceException(String message, Throwable t) {
  37. super(message, t);
  38. this.message = message;
  39. }
  40.  
  41. public String getCode() {
  42. return code;
  43. }
  44.  
  45. public void setCode(String code) {
  46. this.code = code;
  47. }
  48.  
  49. public String getMessage() {
  50. return message;
  51. }
  52.  
  53. public void setMessage(String message) {
  54. this.message = message;
  55. }
  56.  
  57. @Override
  58. public String toString() {
  59. return "ServiceException [code=" + code + ", message=" + message + "]";
  60. }

   2.2 对于全局的异常,我们采用spring的统一进行处理,只需要在代码中进行异常的抛出即可

      核心代码如下:

  1. /**
  2. * 全局异常处理类.对后台直接抛往前台页面的异常进行封装处理.
  3. */
  4. public class ExceptionHandler extends SimpleMappingExceptionResolver {
  5.  
  6. private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
  7.  
  8. @Override
  9. protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
  10. Exception ex) {
  11.  
  12. ModelAndView mv = super.doResolveException(request, response, handler, ex);
  13.  
  14. String url = WebUtils.getPathWithinApplication(request);
  15.  
  16. logger.error("controller error.url=" + url, ex);
  17.  
  18. /* 使用response返回 */
  19. response.setStatus(HttpStatus.OK.value()); // 设置状态码
  20. response.setContentType(MediaType.APPLICATION_JSON_VALUE); // 设置ContentType
  21. response.setCharacterEncoding("UTF-8"); // 避免乱码
  22. response.setHeader("Cache-Control", "no-cache, must-revalidate");
  23.  
  24. JsonResult jsonResult=new JsonResult(JsonResultCode.FAILURE,"系统错误,请联系管理员","");
  25.  
  26. if(ex instanceof ServiceException)
  27. {
  28. ServiceException serviceException=(ServiceException)ex;
  29. String code=serviceException.getCode();
  30. String message=serviceException.getMessage();
  31. jsonResult=new JsonResult(code,message,"");
  32. }
  33. try
  34. {
  35. PrintWriter printWriter = response.getWriter();
  36. printWriter.write(JSONObject.fromObject(jsonResult).toString());
  37. printWriter.flush();
  38. printWriter.close();
  39. } catch (IOException e)
  40. {
  41. logger.error("与客户端通讯异常:" + e.getMessage(), e);
  42. }
  43. logger.error("异常:" + ex.getMessage(), ex);
  44. return mv;
  45. }
  46. }

spring中还需要加上一段这样的配置:

<!-- 全局异常处理.-->
<bean id="exceptionHandler" class="com.netcai.buyer.exception.ExceptionHandler"/>

3. 代码格式方面

   说明:我们控制所有的请求的接口,都需要返回JsonResult对象,另外,我们规定“200”字符串表示请求成功,非“200”表示失败

    相关的代码贴出来,请大家分享:

    

  1. /**
  2. * Controller层的 json格式对象
  3. */
  4. public class JsonResult implements java.io.Serializable {
  5.  
  6. private static final long serialVersionUID = 1L;
  7.  
  8. /**
  9. * 返回的编码
  10. */
  11. private String code;
  12.  
  13. /**
  14. * 返回的信息
  15. */
  16. private String message;
  17.  
  18. /***
  19. * 返回的对象
  20. */
  21. private Object object;
  22.  
  23. public JsonResult() {
  24. super();
  25. }
  26.  
  27. public JsonResult(String code, String message, Object object) {
  28. super();
  29. this.code = code;
  30. this.message = message;
  31. this.object = object;
  32. }
  33.  
  34. public String getCode() {
  35. return code;
  36. }
  37.  
  38. public void setCode(String code) {
  39. this.code = code;
  40. }
  41.  
  42. public String getMessage() {
  43. return message;
  44. }
  45.  
  46. public void setMessage(String message) {
  47. this.message = message;
  48. }
  49.  
  50. public Object getObject() {
  51. return object;
  52. }
  53.  
  54. public void setObject(Object object) {
  55. this.object = object;
  56. }
  57. }

相关的JsonResultCode对象如下:

  1. /**
  2. */
  3. public class JsonResultCode {
  4.  
  5. /**成功**/
  6. public static final String SUCCESS="200";
  7.  
  8. /**失败**/
  9. public static final String FAILURE="201";
  10. }

最终形成了一套完整的数据量的处理,另外还有特殊的情况,比如:404,500等等其他的业务请求,我们应该如何处理的?

由于我们是运行在tomcat下面的,我们在web.xml进行了配置。

代码如下

  1. <error-page>
  2. <exception-type>java.lang.Throwable</exception-type>
  3. <location>/error_500</location>
  4. </error-page>
  5. <error-page>
  6. <exception-type>java.lang.Exception</exception-type>
  7. <location>/error_404</location>
  8. </error-page>
  9. <error-page>
  10. <error-code>500</error-code>
  11. <location>/error_500</location>
  12. </error-page>
  13. <error-page>
  14. <error-code>501</error-code>
  15. <location>/error_500</location>
  16. </error-page>
  17. <error-page>
  18. <error-code>502</error-code>
  19. <location>/error_500</location>
  20. </error-page>
  21. <error-page>
  22. <error-code>404</error-code>
  23. <location>/error_404</location>
  24. </error-page>
  25. <error-page>
  26. <error-code>403</error-code>
  27. <location>/error_404</location>
  28. </error-page>
  29. <error-page>
  30. <error-code>400</error-code>
  31. <location>/error_404</location>
  32. </error-page>

我们把可能出现的任何情况都进行了拦截,然后交给spring来处理这种请求,最终形成一套自己的特殊异常处理

代码如下:

  1. /**
  2. * 错误统一处理
  3. */
  4. @RestController
  5. public class ErrorController {
  6.  
  7. /**
  8. * 请求异常404
  9. * @return
  10. * @throws Exception
  11. */
  12. @RequestMapping(value = "/error_404", method = { RequestMethod.GET, RequestMethod.POST })
  13. public JsonResult error_404() throws Exception
  14. {
  15. return new JsonResult(JsonResultCode.FAILURE, "404请求找不到请求", "");
  16. }
  17.  
  18. /**
  19. * 服务器异常
  20. * @return JsonResult
  21. */
  22. @RequestMapping(value = "/error_500", method = { RequestMethod.GET, RequestMethod.POST })
  23. public JsonResult error_500()
  24. {
  25. return new JsonResult(JsonResultCode.FAILURE, "500服务器内部错误", "");
  26. }
  27. }

总结:我们通过3种情况来进行了所有可能异常的处理,全局异常,业务代码异常,特殊情况异常,架构封装,统一的数据返回与处理等等,进行了完美的结合,该项目运行一年半以来,采用这种异常架构后,从没出现过返回给app什么500错误或者其他乱七八糟的错误,依然是正确的JsonResult对象,APP那边也不用处理特殊情况,一举两得

Java开源生鲜电商平台-异常模块的设计与架构(源码可下载)的更多相关文章

  1. Java开源生鲜电商平台-购物车模块的设计与架构(源码可下载)

    ava开源生鲜电商平台-购物车模块的设计与架构(源码可下载) 说明:任何一个电商无论是B2C还是B2B都有一个购物车模块,其中最重要的原因就是客户需要的东西放在一起,形成一个购物清单,确认是否有问题, ...

  2. Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载) 业务需求: 对于一个B2B的生鲜电商平台,对于买家而言,他需要更加快速的购买到自己的产品,跟自己的餐饮店不相关的东西,他是不关心的,而 ...

  3. Java开源生鲜电商平台-支付模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-支付模块的设计与架构(源码可下载) 开源生鲜电商平台支付目前支持支付宝与微信.针对的是APP端(android or IOS)   1. 数据库表设计. 说明:无论是支付宝还 ...

  4. Java开源生鲜电商平台-售后模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-售后模块的设计与架构(源码可下载) 说明:任何一个的电商平台都有售后服务系统,那么对于我们这个生鲜的电商平台,售后系统需要思考以下几个维度. 1. 买家的需求维度 说明:买家 ...

  5. Java开源生鲜电商平台-账单模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-账单模块的设计与架构(源码可下载) 补充说明:Java开源生鲜电商平台-账单模块的设计与架构,即用户的账单形成过程. 由于系统存在一个押账功能的需求,(何为押账,就是形成公司 ...

  6. Java开源生鲜电商平台-搜索模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-搜索模块的设计与架构(源码可下载) 说明:搜索模块针对的是买家用户,在找菜品找的很费劲下的一种查询方面.目前也是快速的检索商品. 对于移动端的APP买家用户而言,要求的速度在 ...

  7. Java生鲜电商平台-供应链模块的设计与架构

    Java生鲜电商平台-供应链模块的设计与架构 说明:Java开源生鲜电商平台中供应链模块属于卖家的行为,也就是卖家如何管理他们自己的供应商,包括结算方式,压款方式,结算周期等等,超出了我这个B2B平台 ...

  8. Java生鲜电商平台-提现模块的设计与架构

    Java生鲜电商平台-提现模块的设计与架构 补充说明:生鲜电商平台-提现模块的设计与架构,提现功能指的卖家把在平台挣的钱提现到自己的支付宝或者银行卡的一个过程. 功能相对而言不算复杂,有以下几个功能需 ...

  9. Java开源生鲜电商平台-用户表的设计(源码可下载)

    Java开源生鲜电商平台-用户表的设计(源码可下载) 说明:由于该系统属于B2B平台,不设计到B2C的架构. 角色分析:买家与卖家. 由于买家与卖家所填写的资料都不一样,需要建立两站表进行维护,比如: ...

随机推荐

  1. obj-c编程13:归档

    这篇归档内容的博文也挺有趣的,笨猫对好玩的东西一向感兴趣啊!如果用过ruby就会知道,obj-c里的归档类似于ruby中的序列化概念,不过从语法的简洁度来说,我只能又一次呵呵了. 下面大家将会看到2种 ...

  2. Mego(04) - NET简单实现EXCEL导入导出

    前言 相信做过信息系统的朋友都会遇到EXCEL导入导出的相关开发,做过不少EXCEL导入导出后总结起来大致有如下几种方式实现: ADO.NET的OldDb或ODBC连接EXCEL使用DataTable ...

  3. GitHub Desktop 如何创建本地仓库,上传代码,删除仓库

    1.创建本地仓库 2.打开本地仓库,将要上传的文件放到本地仓库. 3.ctrl+p push仓库或者菜单栏Repository下push也可以用右上角的publish respository 4.左边 ...

  4. 使用IntelliJ IDEA的小技巧快乐编程(2)

    前言 本篇介绍的技巧为IntelliJ IDEA中自动代码生成相关的技巧,合理的使用这些技巧将大大提高的你的编码效率 :) Trick 6. 使用模板代码 idea默认的提供了许多模板代码,你可以使用 ...

  5. jbpm 工作流(二)

    1           概述 本文主要介绍如何将JBPM+Struts+Spring+Hibernate整合在一块.并通过一个简单实例来说明.此实例为一个申请审批的简单流程,并将申请人和审批人记录到数 ...

  6. C#解析json的几种方式

    json格式的数据是javascript原生的一种数据格式,比xml更简洁. 它有两种形式:json对象和json对象数组. 在此之前,有必要解释几个基本概念: json字符串,就是string,它一 ...

  7. Install OpenCV on Ubuntu or Debian

    http://milq.github.io/install-OpenCV-ubuntu-debian/转注:就用第一个方法吧,第二个方法的那个sh文件执行失败,因为我价格kurento.org的源,在 ...

  8. 选择Web框架的20条标准

    原文观点由Matt Raible提出,关于Matt Rabile的介绍:http://www.infoq.com/cn/author/Matt-Raible 内容摘自<Java程序员修炼之道&g ...

  9. Pescal Triangle Two

    Description: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3 ...

  10. ArcCore重构-Makefile模块化

    基于官方arc-stable-9c57d86f66be,AUTOSAR版本3.1.5   基本问题 2. 编译系统中代码文件是否编译及目标文件集中定义在boards/board_common.mk,而 ...