REST服务的异常处理

时间:2016-04-14 12:12:03

标签: spring rest

我有一个用户注册的休息服务,所以当有人使用此服务时,会创建一个随机激活密钥,然后如果在发送消息期间没有错误,则将此激活密钥发送给用户的电子邮件。存储到数据库中,将返回带有用户信息的200 HTTP状态。

如果在发送消息期间出现错误,则将重新调整500 HTTP状态,并显示服装消息。

这是我休息服务的代码:

@RequestMapping(value = "/candidats", method = RequestMethod.POST)
    public ResponseEntity<Candidat> saveCandidat(@RequestBody Candidat candidat){

        boolean mailException = false;

        String password=candidat.getPassword();
        String pass=candidat.getPassword();
        password=passwordencoder().encode(password);
        String KeyActivation=UUID.randomUUID().toString();
        candidat.setKeyActivation(KeyActivation);
        candidat.setPassword(password);
        candidat.setActivated(false);

        try{
            emailSender.send(candidat.getEmail(), "Email d'activation du compte", "merci pour votre inscription vous etes la bienvenue\n votre Username est :"+candidat.getUsername()+",et password :"+pass
                    +" merci de cliquer sur ce lien pour acitver votre compte "
                    + "http://localhost:8080/activateAccount?username="+candidat.getUsername()+"&activationKey="+candidat.getKeyActivation());
        }catch (MessagingException e){
            mailException = true;
        }
        if(mailException != false){
            Candidat cand=candidatMetier.saveCandidat(candidat);
            return new ResponseEntity<>(cand, HttpStatus.OK);
        }else{
            return new ResponseEntity<>("Email service is down", HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }

问题是我不知道如何管理这个问题,因为我为ResponseEntity返回了两种不同的类型。

我该如何解决这个问题?

编辑:

我使用spring @ExceptionHandler来处理MessagingException,如下所示:

在我的服务类中:

public Candidat saveCandidat(Candidat candidat) throws MessagingException {

        String password=candidat.getPassword();
        String pass=candidat.getPassword();
        password =  new BCryptPasswordEncoder(12).encode(password);
        String KeyActivation= UUID.randomUUID().toString();
        candidat.setKeyActivation(KeyActivation);
        candidat.setPassword(password);
        candidat.setActivated(false);

        emailSender.send(candidat.getEmail(), "Email d'activation du compte", "merci pour votre inscription vous etes la bienvenue\n votre Username est :"+candidat.getUsername()+",et password :"+pass
                +" merci de cliquer sur ce lien pour acitver votre compte "
                + "http://localhost:8080/activateAccount?username="+candidat.getUsername()+"&activationKey="+candidat.getKeyActivation());

        return candidatRepository.save(candidat);
    }

在我的Rest控制器类中:

@RequestMapping(value = "/candidats", method = RequestMethod.POST)
public ResponseEntity<Candidat> saveCandidat(@RequestBody Candidat candidat) throws MessagingException {

    Candidat cand=candidatMetier.saveCandidat(candidat);
    return new ResponseEntity<>(cand, HttpStatus.OK);

}

@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(MessagingException.class)
@ResponseBody
public String handleMessagingException(){
    return "Email service is down";
}

所以我在这里尝试做的是获取一个INTERNAL_SERVER_ERROR Http状态,其中包含我写的"Email service is down"消息以及我的响应正文中的详细错误ex.getLocalizedMessage();

但我得到了这个:

{
  "timestamp": 1460638057182,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "org.springframework.mail.MailAuthenticationException",
  "message": "Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at\n535 5.7.8  https://support.google.com/mail/answer/14257 7sm6423249wmn.7 - gsmtp\n",
  "path": "/candidats"
}

我无法看到我写的服装信息在哪里。

2 个答案:

答案 0 :(得分:1)

为什么不发送简单发回一个字符串?或者,如果您想在客户端使用该对象,则可以在其中添加变量,并在客户端访问它。

但是,您的控制器中有太多的服务端逻辑,而您正在ResponseEntity<Object>中发送它。这是不必要的。你可以这样做:

    @RequestMapping(value = "/candidats", method = RequestMethod.POST)
        public @ReponseBody Candidat saveCandidat(@RequestBody Candidat candidat){

    Candidat savedObject = this.serviceLayer.saveCandidate(candidate);
return savedObject;
}

在客户端,您可以像这样访问String:

String responseBody = responseEntity.getBody();

然后你可以在客户端采取剩余行动。

答案 1 :(得分:1)

您可以使用SpringMVC提供的ExceptionHandler注释。您也可以使用@ResponseBody代替new ResponseEntity<...>()

@RestController
@RequestMapping(...)
public class CandidateController {

  @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
  @ExceptionHandler(MessagingException.class)
  @ResponseBody
  public String handleMessagingException(MessagingException e)  {
    return "error while sending email.";
  }

  @RequestMapping(value = "/candidats", method = RequestMethod.POST)
  public ResponseEntity<Candidat> saveCandidat(@RequestBody Candidat candidat) throws MessaginException{

    String password=candidat.getPassword();
    String pass=candidat.getPassword();
    password=passwordencoder().encode(password);
    String KeyActivation=UUID.randomUUID().toString();
    candidat.setKeyActivation(KeyActivation);
    candidat.setPassword(password);
    candidat.setActivated(false);

    emailSender.send(candidat.getEmail(), "Email d'activation du compte", "merci pour votre inscription vous etes la bienvenue\n votre Username est :"+candidat.getUsername()+",et password :"+pass
                +" merci de cliquer sur ce lien pour acitver votre compte "
                + "http://localhost:8080/activateAccount?username="+candidat.getUsername()+"&activationKey="+candidat.getKeyActivation());
    Candidat cand=candidatMetier.saveCandidat(candidat);
    return new ResponseEntity<>(cand, HttpStatus.OK);
  }
}

不确定为什么这不适合你。这是一个适合我的最小例子:

@RestController
@RequestMapping("/candidate")
public class CandidateController {

  @Autowired
  CandidatService candidatService;

  @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
  @ExceptionHandler(MessagingException.class)
  @ResponseBody
  public String handleMessagingException(MessagingException e){
    return "error while sending email.";
  }

  @RequestMapping(method = RequestMethod.POST)
  public ResponseEntity<Candidat> saveCandidat(@RequestBody Candidat candidat) throws MessagingException {
    return new ResponseEntity<>(this.candidatService.save(candidat), HttpStatus.OK);
  }
}

@Service
class CandidatService {

  public Candidat save(Candidat candidat) throws MessagingException {
    if(true) {
        throw new MessagingException("foo");
    }
    return candidat;
  }

}