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

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

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

1. 运行的代码异常

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

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

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

    /**
* (商家店铺)商品信息列表
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/goods/list", method = { RequestMethod.GET})
public JsonResult goodsList(HttpServletRequest request, HttpServletResponse response) {
try
{
//业务逻辑处理
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试","");
}catch(Exception ex){
logger.error("[GoodsController][goodsList] exception :",ex);
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试","");
}
}

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

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

2. 全局异常

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

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

  核心代码如下:

/**
* service异常,业务异常继续于当前接口
*
*/
public class ServiceException extends RuntimeException { private static final long serialVersionUID = 4875141928739446984L; /**
* 错误码
*/
protected String code; /**
* 错误信息
*/
protected String message; public ServiceException(String code, String message) {
super();
this.code = code;
this.message = message;
} public ServiceException(String code, String message, Throwable t) {
super();
this.code = code;
this.message = message;
} public ServiceException(String message) {
super(message);
this.message = message;
} public ServiceException(String message, Throwable t) {
super(message, t);
this.message = message;
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} @Override
public String toString() {
return "ServiceException [code=" + code + ", message=" + message + "]";
}

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

      核心代码如下:

/**
* 全局异常处理类.对后台直接抛往前台页面的异常进行封装处理.
*/
public class ExceptionHandler extends SimpleMappingExceptionResolver { private static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class); @Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) { ModelAndView mv = super.doResolveException(request, response, handler, ex); String url = WebUtils.getPathWithinApplication(request); logger.error("controller error.url=" + url, ex); /* 使用response返回 */
response.setStatus(HttpStatus.OK.value()); // 设置状态码
response.setContentType(MediaType.APPLICATION_JSON_VALUE); // 设置ContentType
response.setCharacterEncoding("UTF-8"); // 避免乱码
response.setHeader("Cache-Control", "no-cache, must-revalidate"); JsonResult jsonResult=new JsonResult(JsonResultCode.FAILURE,"系统错误,请联系管理员",""); if(ex instanceof ServiceException)
{
ServiceException serviceException=(ServiceException)ex;
String code=serviceException.getCode();
String message=serviceException.getMessage();
jsonResult=new JsonResult(code,message,"");
}
try
{
PrintWriter printWriter = response.getWriter();
printWriter.write(JSONObject.fromObject(jsonResult).toString());
printWriter.flush();
printWriter.close();
} catch (IOException e)
{
logger.error("与客户端通讯异常:" + e.getMessage(), e);
}
logger.error("异常:" + ex.getMessage(), ex);
return mv;
}
}

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

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

3. 代码格式方面

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

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

    

/**
* Controller层的 json格式对象
*/
public class JsonResult implements java.io.Serializable { private static final long serialVersionUID = 1L; /**
* 返回的编码
*/
private String code; /**
* 返回的信息
*/
private String message; /***
* 返回的对象
*/
private Object object; public JsonResult() {
super();
} public JsonResult(String code, String message, Object object) {
super();
this.code = code;
this.message = message;
this.object = object;
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} public Object getObject() {
return object;
} public void setObject(Object object) {
this.object = object;
}
}

相关的JsonResultCode对象如下:

/**
*/
public class JsonResultCode { /**成功**/
public static final String SUCCESS="200"; /**失败**/
public static final String FAILURE="201";
}

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

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

代码如下

<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error_500</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error_404</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error_500</location>
</error-page>
<error-page>
<error-code>501</error-code>
<location>/error_500</location>
</error-page>
<error-page>
<error-code>502</error-code>
<location>/error_500</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error_404</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/error_404</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/error_404</location>
</error-page>

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

代码如下:

/**
* 错误统一处理
*/
@RestController
public class ErrorController { /**
* 请求异常404
* @return
* @throws Exception
*/
@RequestMapping(value = "/error_404", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult error_404() throws Exception
{
return new JsonResult(JsonResultCode.FAILURE, "404请求找不到请求", "");
} /**
* 服务器异常
* @return JsonResult
*/
@RequestMapping(value = "/error_500", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult error_500()
{
return new JsonResult(JsonResultCode.FAILURE, "500服务器内部错误", "");
}
}

总结:我们通过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. mac os x下的一些小技巧

    1显示swap空间: sysctl vm.swapusage 其中sysctl中有很多可以控制和查看的项,可以通过sysctl -A列举,另外可以通过man sysctl来查看. 而实际swap文件和 ...

  2. linux 常见命令及说明杂记

    systemctl 命令: systemctl 是管制服务的主要工具, 它整合了chkconfig 与 service功能于一体.示例:systemctl is-enabled iptables.se ...

  3. 9.3.3 scrapy 框架

    scrapy是一个非常好用的Web爬虫框架,非常适合抓取Web站点从网页中提取结构化的数据,并且支持自定义的需求.在使用scrapy爬取网页数据时,除了熟悉HTML标签,还需要了解目标网页的数据组织结 ...

  4. 使用nginx sticky实现基于cookie的负载均衡

    在多台后台服务器的环境下,我们为了确保一个客户只和一台服务器通信,我们势必使用长连接.使用什么方式来实现这种连接呢,常见的有使用nginx自带的ip_hash来做,我想这绝对不是一个好的办法,如果前端 ...

  5. Day16 Django

    学Django之前,先看下http基础,老师的网页地址: web框架 - Yuan先生 - 博客园 http://www.cnblogs.com/yuanchenqi/articles/7690561 ...

  6. eclipse更新time out的问题

    因为网络等诸方面的原因,中国国内访问download.eclipse.org非常慢,更新往往都会失败,简单解决的是从eclipse官网下载镜像列表中选一个中国镜像设为更新站点,当然这个镜像的选择,需要 ...

  7. JSP Debug日志

    2006年末一篇blog,那时候好生涩啊: 先谈两个关于reponse.sendRedirect()函数的问题 :      1.在Servlet的处理流或JSP的页面流中,sendRedirect( ...

  8. Python2和Python3的差异

    之前做Spark大数据分析的时候,考虑要做Python的版本升级,对于Python2和Python3的差异做了一个调研,主要对于语法和第三方工具包支持程度进行了比较. 基本语法差异 核心类差异 Pyt ...

  9. ArcticCore重构-VALIDATE_%

    基于官方arc-stable-9c57d86f66be,AUTOSAR版本3.1.5 基本问题 Arctic Core中使用了VALIDATE, VALIDATE_RV, VALIDATE_NO_RV ...

  10. 【Java】运用泽勒一致性计算某天是星期几

    /** * Created by liangjiahao on 2017/2/26. * 运用泽勒一致性计算某天是星期几? * 公式: * h = (q + 26(m+1)/10 + k +k/4 + ...