一个简单的java异常设计

java的异常分为两类:
1.error:jvm错误造成无法被程序员处理
2.Exception:可以由程序员有针对性的处理
因此我们需要关注的就是Exception,通常我们都只是针对程序本身的业务逻辑进行设计进而忽视了对异常处理的设计而这显然是不好的。
现在就以用户登陆这个流程来设计一个简单的异常处理设计
流程十分简单:用户表单提交数据->后台校验数据->反馈登陆结果
##异常基类
首先我们自定义一个通用的异常基类,该类继承自RuntimeException

package com.hw.myp2c.common.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author chengjian
 * @description
 * @date 18-11-10:上午11:28
 */
public class GenericException extends RuntimeException{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     *
     * @param message the detail message. The detail message is saved for
     *                later retrieval by the {@link #getMessage()} method.
     */
    public GenericException(String message) {
        super(message);
        logger.error(message);
    }

    /**
     * Constructs a new runtime exception with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * {@code cause} is <i>not</i> automatically incorporated in
     * this runtime exception's detail message.
     *
     * @param message the detail message (which is saved for later retrieval
     *                by the {@link #getMessage()} method).
     * @param cause   the cause (which is saved for later retrieval by the
     *                {@link #getCause()} method).  (A <tt>null</tt> value is
     *                permitted, and indicates that the cause is nonexistent or
     *                unknown.)
     * @since 1.4
     */
    public GenericException(String message, Throwable cause) {
        super(message, cause);
        logger.error(message, cause);
    }
}

所有自定义的异常类都继承自该类
##数据库层异常类
在数据库操作层面定义类ItemsNotFoundException字面意思也能明白这个类的作用用户告知上层调用没有从数据库找到该用户

package com.hw.myp2c.common.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author chengjian
 * @description
 * @date 18-11-10:上午11:28
 */
public class ItemsNotFoundException extends GenericException {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     *
     * @param message the detail message. The detail message is saved for
     *                later retrieval by the {@link #getMessage()} method.
     */
    public ItemsNotFoundException(String message) {
        super(message);
        logger.error(message);
    }

    /**
     * Constructs a new runtime exception with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * {@code cause} is <i>not</i> automatically incorporated in
     * this runtime exception's detail message.
     *
     * @param message the detail message (which is saved for later retrieval
     *                by the {@link #getMessage()} method).
     * @param cause   the cause (which is saved for later retrieval by the
     *                {@link #getCause()} method).  (A <tt>null</tt> value is
     *                permitted, and indicates that the cause is nonexistent or
     *                unknown.)
     * @since 1.4
     */
    public ItemsNotFoundException(String message, Throwable cause) {
        super(message, cause);
        logger.error(message,cause);
    }
}

##业务异常类
在本示例中的体现就是用户登陆失败所以我们定义了UserLoginException

package com.hw.myp2c.common.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author chengjian
 * @version 1.0
 * @date 2018-11-10
 * @Description
 */

public class UserLoginException extends GenericException {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     *
     * @param message the detail message. The detail message is saved for
     *                later retrieval by the {@link #getMessage()} method.
     */
    public UserLoginException(String message) {
        super(message);
        logger.error(message);
    }
}

##异常调用实现
在定义好异常类基础上展示对用户登陆这一流程的异常处理

public interface Myp2cUserService extends BaseService<Myp2cUserEntity,String> {

    /**
     * @author chengjian
     * @description 根据用户名获取用户信息
     * @date 18-11-10:下午4:11
     * @param  userId
     * @return com.hw.myp2c.user.entity.Myp2cUserEntity
     */
    Myp2cUserEntity loadUserByUserId(String userId) throws ItemsNotFoundException;
}
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class Myp2cUserServiceImpl extends BaseServiceImpl<Myp2cUserEntity, String> implements Myp2cUserService {
    private Myp2cUserDao myp2cUserDao;

    @Autowired
    public Myp2cUserServiceImpl(Myp2cUserDao myp2cUserDao) {
        this.myp2cUserDao = myp2cUserDao;
    }

    /**
     * @param userId
     * @return com.hw.myp2c.user.entity.Myp2cUserEntity
     * @author chengjian
     * @description 根据用户名获取用户信息
     * @date 18-11-10:下午4:11
     */
    @Override
    public Myp2cUserEntity loadUserByUserId(String userId) throws ItemsNotFoundException {
        try {
            Myp2cUserEntity userEntity = myp2cUserDao.findFirstByUserId(userId);
            if (userEntity == null) {
                throw new ItemsNotFoundException("未找到该用户!");
            }
            return userEntity;
        } catch (Exception e) {
            throw new ItemsNotFoundException("登陆出错,请联系管理员!");
        }

    }
}

从代码看到对数据库的查询产生2个异常
1.执行数据库查询时产生异常
2.没有找到用户
这两个异常最终导致的结果就是没有找到该用户信息,所以抛出了ItemsNotFoundException

public interface SecurityService {

    /**
     * @param userId
     * @param userPwd
     * @return 
     * @author chengjian
     * @description 用户登陆
     * @date 18-11-10:下午6:48
     */
    Myp2cUserEntity userLogin(String userId, String userPwd) throws UserLoginException;
}

@Service
public class SecurityServiceImpl implements SecurityService {

    private Myp2cUserService myp2cUserService;
    private Myp2cRoleService myp2cRoleService;
    private Myp2cMidsService myp2cMidsService;

    @Autowired
    public SecurityServiceImpl(Myp2cUserService myp2cUserService, Myp2cRoleService myp2cRoleService, Myp2cMidsService myp2cMidsService) {
        this.myp2cUserService = myp2cUserService;
        this.myp2cRoleService = myp2cRoleService;
        this.myp2cMidsService = myp2cMidsService;
    }

    /**
     * @param userId
     * @param userPwd
     * @return java.lang.String
     * @author chengjian
     * @description 用户登陆
     * @date 18-11-10:下午6:48
     */
    @Override
    public Myp2cUserEntity userLogin(String userId, String userPwd) {
        try {
            Myp2cUserEntity userEntity = myp2cUserService.loadUserByUserId(userId);
            String encodePwd = MD5Util.MD5(userPwd);
            if (!encodePwd.equalsIgnoreCase(userEntity.getUserPwd())) {
                throw new UserLoginException("用户名或密码错误!");
            }
            List<Myp2cRoleEntity> roles = myp2cRoleService.findByUser(userId);
            roles.forEach(role -> role.setRoleMids(myp2cMidsService.findByRole(role.getId())));
            userEntity.setUserRoles(roles);
            userEntity.setMenuHtml(Mids.createUserMenuHtml(userEntity.initUserMids(), userId));
            return userEntity;
        } catch (ItemsNotFoundException e) {
            throw new UserLoginException(e.getMessage());
        }
    }
}

从代码看到在本业务类中捕获ItemsNotFoundException并针对用户登陆校验情况产生UserLoginException

/**
 * @author chengjian
 * @version 1.0
 * @date 2018-11-10
 * @Description
 */

@RestController
public class SecurityController {
    private SecurityService securityService;

    @Autowired
    public SecurityController(SecurityService securityService) {
        this.securityService = securityService;
    }

    @PostMapping
    public String login(@RequestParam(required = true)String userId,@RequestParam(required = true)String userPwd){
        try {
            Myp2cUserEntity userEntity=securityService.userLogin(userId,userPwd);
            return userEntity.user2JsonString();
        }catch (UserLoginException e){
            return e.getMessage();
        }

    }
}

最终在controller中对异常进行处理并将封装好的错误信息返回给用户
通过异常的方式来返回信息比通过设置各种返回代码(1:成功;0:失败)这一方式来返回结果信息更有逻辑性,同时也能提高代码的可读性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值