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. obj-c编程15[Cocoa实例01]:一个会发声的随机数生成器

    哇!终于到了obj-c编程系列的第15篇喽,一路走过来满不容易的哦!(怎么个意思,这才哪到哪啊!),为了能够更好的练习obj-c在Cocoa框架上的编程,接下来会以N篇Cocoa实例的博文来巩固和记忆 ...

  2. plsql developer 使用 oracle instantclient的安装和配置

    本文由ibyedo1贡献 1.下载 oracle instantclient basic package,在 oracle 官网下载就可以,地址如下: http://www.oracle.com/te ...

  3. 第15章-输入/输出 --- 理解Java的IO流

    (一)理解Java的IO流 JAVA的IO流是实现输入/输出的基础,它可以方便地实现数据的输入/输出操作,在Java中把不同的输入/输出(键盘.文件.网络连接等)抽象表述为"流"( ...

  4. gdb命令中attach使用

    [测试程序] 我们先看看我们的测试程序: /* in eg1.c */ int wib(int no1, int no2) {         int result, diff;         di ...

  5. 导入项目 idea

    下的java核心编程的源码,只有java文件,没有idea或者eclipse的项目结构信息. 分别用eclipse和idea打开了一遍,方便学习调试. 项目文件夹:E:\学习资料\Java\语法\ja ...

  6. (一)SpringBoot基础篇- 介绍及HelloWorld初体验

    1.SpringBoot介绍: 根据官方SpringBoot文档描述,BUILD ANYTHING WITH SPRING BOOT (用SPRING BOOT构建任何东西,很牛X呀!),下面是官方文 ...

  7. python爬虫入门(七)Scrapy框架之Spider类

    Spider类 Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作 ...

  8. 源码分析Session的台前幕后(Asp .Net MVC5)

    在这篇文章里,我们从源代码的角度重点分析Session的创建.缓存.销毁.管理. 通常我们说的Session指的是在控制器中使用的Session字段,该字段的类型是HttpSessionState.可 ...

  9. springboot集成rabbitmq(实战)

    RabbitMQ简介RabbitMQ使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现(AMQP的主要特征是面向消息.队列.路由.可靠性.安全).支持多种客户端,如:Python.Ru ...

  10. 【转】深入理解margin

    由浅入深漫谈margin属性 2007-3-18 上午 - HTML/CSS/XML/XSL - CSS - margin margin 在中文中我们翻译成外边距或者外补白(本文中引用外边距).他是元 ...