首页 \ 问答 \ Springboot错误处理(Springboot error handling)

Springboot错误处理(Springboot error handling)

我正在开发一个处理登录的示例spring-boot API,但是API工作正常,但在处理错误时遇到问题。 我在教程中看到的所有错误处理都是在控制器中完成的,但是我的逻辑处于服务中,并且在那里我想进行错误处理。

我怎样才能在服务中实现错误处理不同类型的错误,或者是否认为这是错误的做法。 我目前的问题是,我的错误消息如下所示:

{

 "message": "Please Activate account before attempting to Sign in",
  "token": " ",
  "accountLocked": false,
  "accountEnabled": false,
  "status": false,
  "balance": " ",
  "profileImage": null,
  "roles": null,
  "baraAuthorities": null,
  "customerNumber": 0,
  "userEmail": "",
  "name": ""
}

不过,我希望只有消息和状态显示并隐藏了答案中的其余部分,我该如何实现这一点:

{
  "message": "Please Activate account before attempting to Sign in",
  "status": false
}

这是我的LoginService代码:

@Service
public class LoginService implements UserDetailsService {

    @Autowired
    private UserLoginRepository loginRepository;
    @Autowired
    private LoginInformationRepository logininfoRepository;

    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    String balance, message, pin, token, userEmail, name, profileImage = "";
    Boolean status, successStatus, accounState = false;
    int customerNumber, attempts;
    List<Roles> userRoles = new ArrayList();

    private boolean userNameExist(String username) {
        UserLogin user = loginRepository.findByUsername(username);
        if (user != null) {
            return true;
        }
        return false;
    }

    public LoginResponse verifyLoginDetails(LoginObject user) throws LoginException {

        AuthoritiesKeys userAuth = new AuthoritiesKeys();
        Merchant searchedMerchant = merchantRepository.findByUserlogin_LoginCredentialsID(userdetails.getLoginCredentialsID());
        DateUtility currentDate = new DateUtility();
        Boolean status = false;

        if (userdetails == null) {
            return new LoginResponse("Unable to Login. Please check login details and try again",status);
        } else {

            pin = user.getPassword();
            attempts = logininfoRepository.countByTodayDateAndUserLoginLoginCredentialsIDAndLoginSuccessStatusFalse(currentDate.getCurrentDate(), userdetails.getLoginCredentialsID());
            if (attempts < 3) {
                if (bCryptPasswordEncoder.matches(pin, userdetails.getPassword())) {

                    if (userdetails.isEnabled() == true) {
                        if (searchedMerchant != null) {

                            message = "Logged in Successfully";
                            status = userdetails.isAccountNonLocked();
                            accounState = userdetails.isEnabled();
                            userRoles = (List<Roles>) userdetails.getAuthorities();
                            balance = searchedMerchant.getAccount().getBalance().toString();
                            successStatus = true;
                            customerNumber = searchedMerchant.getMerchantNumber();
                            userEmail = searchedMerchant.getEmail();
                            name = searchedMerchant.getBusinessName();

                            return new LoginResponse(message, token, accounState, status, userRoles, successStatus, balance, userAuth, profileImage, customerNumber, userEmail, name);

                        } else {
                            return new LoginResponse("Error Merchant Information Error . Please contact the team",status);
                        }

                    } else {
                        return new LoginResponse("Please Activate account before attempting to Sign in",status);
                    }
                } else {
                    return new LoginResponse("Wrong Username or Password",status);
                }

            } else {
                userdetails.setAccountNonLocked(false);
                userdetails.setEnabled(false);
                loginRepository.save(userdetails);
                return new LoginResponse("Too many attempts account has been locked",status);
            }


        }

    }

这是我的LoginResponse代码:

 public class LoginResponse {

    private String message;
    private String token;
    private Boolean accountLocked;
    private Boolean accountEnabled;
    private Boolean status;
    private String balance;
    private String profileImage;
    List<Roles> roles = new ArrayList<>();
    AuthoritiesKeys baraAuthorities = new AuthoritiesKeys();
    private int customerNumber;
    private String userEmail;
    private String name;

    public LoginResponse() {
    }

    public LoginResponse(String message, Boolean status) {
        this.message = message;
        this.status = status;
    }

    public LoginResponse(String message, String token, Boolean accountLocked, Boolean accountEnabled, List<Roles> myroles, Boolean status, String balance, AuthoritiesKeys userBaraAuthorities, String profileImage, int customerNumber, String userEmail, String name) {
        this.message = message;
        this.token = token;
        this.accountLocked = accountLocked;
        this.accountEnabled = accountEnabled;
        this.status = status;
        this.balance = balance;
        this.roles = myroles;
        this.baraAuthorities = userBaraAuthorities;
        this.profileImage = profileImage;
        this.customerNumber = customerNumber;
        this.userEmail = userEmail;
        this.name = name;
    }

… // left getter and setters for brevity

}

这是我的LoginController代码:

@RestController
@Api(value = "Login API", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserLoginController {

    @Autowired
    private LoginService loginService;
    @RequestMapping(method = RequestMethod.POST, value = "/api/usermanagement/user/login")
    @ApiOperation("login registered user")
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = ResponseMessage.class)})
    public LoginResponse Login(@Valid @RequestBody LoginObject credentails) throws LoginException {
        return loginService.verifyLoginDetails(credentails);

    }

}

I am developing a sample spring-boot API that handles login, the API works fine however , I am having a problem during error handling. All the error handling I have seen in tutorials is done in the controller, however my logic is in the service and thats where I would like to do error handling.

How can I achieve error handling of different type of errors in the service or is it considered bad practice to do so. My current problem is that my error message looks like this :

{

 "message": "Please Activate account before attempting to Sign in",
  "token": " ",
  "accountLocked": false,
  "accountEnabled": false,
  "status": false,
  "balance": " ",
  "profileImage": null,
  "roles": null,
  "baraAuthorities": null,
  "customerNumber": 0,
  "userEmail": "",
  "name": ""
}

However I would like to have just the message and the status show and hide the rest in the response, how do I achieve this :

{
  "message": "Please Activate account before attempting to Sign in",
  "status": false
}

This is my code for LoginService :

@Service
public class LoginService implements UserDetailsService {

    @Autowired
    private UserLoginRepository loginRepository;
    @Autowired
    private LoginInformationRepository logininfoRepository;

    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    String balance, message, pin, token, userEmail, name, profileImage = "";
    Boolean status, successStatus, accounState = false;
    int customerNumber, attempts;
    List<Roles> userRoles = new ArrayList();

    private boolean userNameExist(String username) {
        UserLogin user = loginRepository.findByUsername(username);
        if (user != null) {
            return true;
        }
        return false;
    }

    public LoginResponse verifyLoginDetails(LoginObject user) throws LoginException {

        AuthoritiesKeys userAuth = new AuthoritiesKeys();
        Merchant searchedMerchant = merchantRepository.findByUserlogin_LoginCredentialsID(userdetails.getLoginCredentialsID());
        DateUtility currentDate = new DateUtility();
        Boolean status = false;

        if (userdetails == null) {
            return new LoginResponse("Unable to Login. Please check login details and try again",status);
        } else {

            pin = user.getPassword();
            attempts = logininfoRepository.countByTodayDateAndUserLoginLoginCredentialsIDAndLoginSuccessStatusFalse(currentDate.getCurrentDate(), userdetails.getLoginCredentialsID());
            if (attempts < 3) {
                if (bCryptPasswordEncoder.matches(pin, userdetails.getPassword())) {

                    if (userdetails.isEnabled() == true) {
                        if (searchedMerchant != null) {

                            message = "Logged in Successfully";
                            status = userdetails.isAccountNonLocked();
                            accounState = userdetails.isEnabled();
                            userRoles = (List<Roles>) userdetails.getAuthorities();
                            balance = searchedMerchant.getAccount().getBalance().toString();
                            successStatus = true;
                            customerNumber = searchedMerchant.getMerchantNumber();
                            userEmail = searchedMerchant.getEmail();
                            name = searchedMerchant.getBusinessName();

                            return new LoginResponse(message, token, accounState, status, userRoles, successStatus, balance, userAuth, profileImage, customerNumber, userEmail, name);

                        } else {
                            return new LoginResponse("Error Merchant Information Error . Please contact the team",status);
                        }

                    } else {
                        return new LoginResponse("Please Activate account before attempting to Sign in",status);
                    }
                } else {
                    return new LoginResponse("Wrong Username or Password",status);
                }

            } else {
                userdetails.setAccountNonLocked(false);
                userdetails.setEnabled(false);
                loginRepository.save(userdetails);
                return new LoginResponse("Too many attempts account has been locked",status);
            }


        }

    }

This is my code for LoginResponse :

 public class LoginResponse {

    private String message;
    private String token;
    private Boolean accountLocked;
    private Boolean accountEnabled;
    private Boolean status;
    private String balance;
    private String profileImage;
    List<Roles> roles = new ArrayList<>();
    AuthoritiesKeys baraAuthorities = new AuthoritiesKeys();
    private int customerNumber;
    private String userEmail;
    private String name;

    public LoginResponse() {
    }

    public LoginResponse(String message, Boolean status) {
        this.message = message;
        this.status = status;
    }

    public LoginResponse(String message, String token, Boolean accountLocked, Boolean accountEnabled, List<Roles> myroles, Boolean status, String balance, AuthoritiesKeys userBaraAuthorities, String profileImage, int customerNumber, String userEmail, String name) {
        this.message = message;
        this.token = token;
        this.accountLocked = accountLocked;
        this.accountEnabled = accountEnabled;
        this.status = status;
        this.balance = balance;
        this.roles = myroles;
        this.baraAuthorities = userBaraAuthorities;
        this.profileImage = profileImage;
        this.customerNumber = customerNumber;
        this.userEmail = userEmail;
        this.name = name;
    }

… // left getter and setters for brevity

}

This my code for LoginController :

@RestController
@Api(value = "Login API", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserLoginController {

    @Autowired
    private LoginService loginService;
    @RequestMapping(method = RequestMethod.POST, value = "/api/usermanagement/user/login")
    @ApiOperation("login registered user")
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK", response = ResponseMessage.class)})
    public LoginResponse Login(@Valid @RequestBody LoginObject credentails) throws LoginException {
        return loginService.verifyLoginDetails(credentails);

    }

}

原文:https://stackoverflow.com/questions/50520010
更新时间:2023-07-16 17:07

最满意答案

解决这个问题的一种方法是首先将Door *关闭。 但是,为了减少这种类型的安全性,你应该使用dynamic_cast<Door *>() 。 如果Entity还没有虚拟方法,则可以添加虚拟析构函数。

class Entity {
    //...
    virtual ~Entity () {}
};

void foo (Entity *e) {
    //...
    Door *door = dynamic_cast<Door *>(e);
    if (door) {
        if (door->isOpen()) {
            //...
        }
    }
    //...
}

One way to solve this is with a down cast to a Door * first. However, in order for this down cast to be type safe, you should use dynamic_cast<Door *>(). If Entity does not already have a virtual method, you can add a virtual destructor.

class Entity {
    //...
    virtual ~Entity () {}
};

void foo (Entity *e) {
    //...
    Door *door = dynamic_cast<Door *>(e);
    if (door) {
        if (door->isOpen()) {
            //...
        }
    }
    //...
}

相关问答

更多
  • 这是一如既往的旧规则 每一个new应该只有一个delete 在你的情况下,你唯一一次调用new就是分配一个Test实例(并且不清楚你为什么这么做,但让我们忽略它)。 然后将该对象的副本插入到vector ; 你没有为插入的对象分配内存。 所以没有必要在vector管理的内存上调用delete 。 另一方面,您正在泄漏内存,因为您从未在已分配的内存上调用delete 。 添加一个 delete t; 在你完成使用t之后的代码中 现在,如果您的向量被声明为vector ,则需要在从向量中移除元 ...
  • 它适用于我的编译器....获取实例的地址然后解除引用它与不执行所有操作相同。 所以你不需要它。 所以取而代之 *(&nodes[i].nx)=newNXValue; 同 nodes[i].nx = newNXValue; 这是我尝试的代码示例: #include "stdafx.h" #include #include struct Rz3DContourNode { float x; float y; float z; float nx; f ...
  • 向量管理单个连续的对象数组,因此它不需要指向每个元素的指针。 它只需要: 指向数组开头的指针 标记所用元素结尾的指针(或索引)(即大小) 标记已分配存储结束的指针(或索引)(即容量) (它还需要存储一个分配器;但通常,这是无状态的,一个不错的实现将使用“空基类优化”来确保它在这种情况下不占用空间)。 如果您管理自己的动态阵列,则至少需要其中两个; 因此使用向量的额外成本是单个指针。 如果您不需要动态分配,那么自动数组(或std::array ,如果您想要更多STLy)将更有效:它不会涉及任何堆分配或任何额外 ...
  • 解决这个问题的一种方法是首先将Door *关闭。 但是,为了减少这种类型的安全性,你应该使用dynamic_cast() 。 如果Entity还没有虚拟方法,则可以添加虚拟析构函数。 class Entity { //... virtual ~Entity () {} }; void foo (Entity *e) { //... Door *door = dynamic_cast(e); if (door) { if ...
  • 既然你是通过价值传递他们,你正在应付每一个你正在做的电话中的vector和map 。 我认为这使得结果几乎没有意义。 将它们作为引用或const引用传递并再次运行测试。 template int GetPosition(const vector& mVec, T element) { return find(mVec.begin(), mVec.end(), element) - mVec.begin(); } template int GetPosi ...
  • 在C ++ 11下,你可以使用lambda表达式,它比古老的bind2nd容易得多。 例如: #include #include #include #include class Class1 { public: Class1(const std::string& name) : Name(name) { } const std::string& getName() const { re ...
  • 您可能想让grab返回引用而不是副本: csv_File& grab(int index); You probably want to make grab return a reference rather than a copy: csv_File& grab(int index);
  • 返回const rvalue是C ++ 11中的反模式。 首先考虑返回非const rvalues: std::vector f(int n) { return std::vector(n); } int main() { std::vector v; v = f(3); } 在C ++ 98/03中,此代码将至少进入堆两次: 在f内创建向量(如果RVO适用) 从f的回归分配给v。 如果您的编译器不应用RVO,则会获得3个堆分配。 在 ...
  • 您不能直接调用带有STL容器的Native函数。 您应该编写一个包装器并手动将SV *转换为STL容器。 如果您不知道如何做到这一点(就像我一样),请尝试使用SWIG http://www.swig.org/ 它可以为本机函数生成包装器,以便从脚本语言(包括PERL和XS生成器)中使用它。 来自SWIG的代码不是很漂亮,也有一些限制,但它是编写包装器的简单方法。 SWIG对STL内置的支持有限: http : //www.swig.org/Doc1.3/Library.html#Library_stl_cp ...
  • 在堆上的连续内存块中。 vector以与new int[x]相同的方式分配内存。 仅当您使用at方法时。 如果边界检查失败,它会抛出std::out_of_range异常。 operator[]不执行边界检查。 因为数组可以直接访问内存,所以访问向量元素很可能涉及方法调用。 但差异可能非常小,特别是如果您的编译器决定内联调用。 通常,如果希望容器具有动态大小,则使用vector如果已知固定大小足够,则使用简单数组。 请务必查看其他容器,例如deque和list ,以确保选择最合适的容器。 否则,如 ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。