Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧启动休息控制器。返回对象,包括传统属性和异常处理_Java_Spring_Spring Boot_Spring Data - Fatal编程技术网

Java 弹簧启动休息控制器。返回对象,包括传统属性和异常处理

Java 弹簧启动休息控制器。返回对象,包括传统属性和异常处理,java,spring,spring-boot,spring-data,Java,Spring,Spring Boot,Spring Data,我在春天遇到了麻烦 用户服务 @Service public class UserService implements IUserService { @Autowired public PasswordEncoder passwordEncoder; private final UserRepository userRepository; public UserService(UserRepository userRepository) {

我在春天遇到了麻烦

用户服务

@Service
public class UserService implements IUserService {

    @Autowired
    public PasswordEncoder passwordEncoder;

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public UserLoginResponse register(RegisterUserRequest request) throws NoValidRegisterDataException, Exception {
        UserLoginResponse response = new UserLoginResponse();
        UserEntity user = request.getUser();

        if(!this.checkUserDataValidity(user)) {
            throw new NoValidRegisterDataException();
        }

        user.setPassword(this.encodePassword(user.getPassword()));

        try {
            user = this.userRepository.save(user);
        } catch (Exception e) {
            throw new Exception("Database save error");
        }

        response.addMessage(new ResponseMessage(ResponseMessageType.success, "Uživatel úspěšně registrován"));
        response.setUser(user);

        //TODO token handler

        return response;
    }

    private boolean checkUserDataValidity(UserEntity user) {
        return (user.getEmail() != null && user.getPassword() != null && user.getUsername() != null);
    }

    private String encodePassword(String password) {
        return this.passwordEncoder.encode(password);
    }
}
到目前为止,我有一个服务注册(主要方法)。它由UserController调用(下面的代码)

我返回UserLoginResponse对象。我在请求中获取RegisterUserRequest对象(它基本上是包含用户数据的对象)

公共类UserLoginResponse扩展响应{
私有用户实体用户;
私有字符串用户令牌;
公共用户登录响应(){}
公共UserLoginResponse(ArrayList消息、UserEntity用户、字符串userToken){
超级(信息);
this.user=用户;
this.userToken=userToken;
}
公共用户实体getUser(){
返回用户;
}
public void setUser(UserEntity用户){
this.user=用户;
}
公共字符串getUserToken(){
返回userToken;
}
公共void setUserToken(字符串userToken){
this.userToken=userToken;
}
}
它扩展了响应对象,该对象内部有一个属性。要发送到前端的邮件列表

public class Response {
    private ArrayList<ResponseMessage> messages;

    public Response() {}

    public Response(ArrayList<ResponseMessage> messages) {
        this.messages = messages;
    }

    public void addMessage(ResponseMessage message) {
        if(this.messages == null) {
            this.messages = new ArrayList<>();
        }

        this.messages.add(message);
    }
}
公共类响应{
私有数组列表消息;
公共响应(){}
公共响应(ArrayList消息){
this.messages=消息;
}
公共无效添加消息(响应消息消息){
if(this.messages==null){
this.messages=new ArrayList();
}
this.messages.add(message);
}
}
第一个问题是,当发生错误时(坏的用户数据、其他错误),我会得到空的UserLoginResponse对象。基本上没关系,但我没有留言。(错误消息设置在UserController的catch块中,因此它们应该在那里。)

第二个问题是,即使我在UserController的第一个catch块中抛出NoValidRegisterDataException(在常规异常上),该异常也由最后一个catch块处理。我怎样才能解决这个问题?我认为异常是由它适合的第一个catch块(从上到下)处理的


编辑:我已经解决了第二个问题。我没有注意到在条件up时抛出的异常是抛出的nullpointerexception。因此,现在有意义了。我添加了空检查,异常现在可以正常工作了。但是我仍然不知道如何返回整个响应,包括来自父响应对象的消息。

我认为您的代码有几个问题:

1) 请避免在Spring服务和控制器中使用选中的异常。它们只增加了噪音,尤其是各种try-catch子句。理想情况下,如果想要抛出异常,只需抛出一个运行时异常,并准备一个异常处理程序来捕获它并创建适当的响应。您可以在此处查看这些:

2) 避免使用catch子句捕获
异常
。在大多数情况下,如果发生一些不必要的异常,这将打乱您的流程。让它冒泡到Spring的默认异常处理程序

3) 避免继承,作为回报,只支持组合。在我看来,扩展POJO不是一件很好的事情

4) 避免现场注入和构造函数注入的混合。在大多数情况下,这是造成灾难的原因


5) 我认为每次手动设置servletResponse没有任何意义。只需将响应对象包装成一个
ResponseEntity
,它还可以有效地携带一个状态代码。

好吧,除了继承之外,我还能处理这个问题吗?我有几种行为,几种反应。所有的回答都有共同点。响应数组(它们将在前端显示给用户)。可能有0..N条带有其他文本和类型(危险、成功等)的消息。另外,我需要让用户知道API出了问题。因此,如果他没有填充所有notnull属性,他需要得到描述错误的错误消息。如何在没有自定义异常的情况下执行此操作?可以有两个不同的响应对象,它们不会彼此扩展。另外,如果您查看
ResponseEntity
文档,您将看到它能够携带一个主体,这意味着在出现错误的情况下,您可以简单地用错误列表进行响应(不需要为此使用另一个响应对象)。此外,我没有说不要使用任何自定义异常,我只是说要支持运行时异常,并使用Spring的处理方式。请检查我提供的链接。但是当我想返回对象时,例如用户列表和消息列表(我需要该列表,即使没有出错。例如“数据加载成功”消息)。例如,我将返回回复。在应用程序中,我需要X个带有其他数据的响应,但仍然带有消息数组。在所有这些对象中具有所有消息列表的属性,而不是具有这些响应扩展的父对象,这真的是一个好主意吗?将会有很多代码重复。
public class UserLoginResponse extends Response {
    private UserEntity user;

    private String userToken;

    public UserLoginResponse() {}

    public UserLoginResponse(ArrayList<ResponseMessage> messages, UserEntity user, String userToken) {
        super(messages);
        this.user = user;
        this.userToken = userToken;
    }

    public UserEntity getUser() {
        return user;
    }

    public void setUser(UserEntity user) {
        this.user = user;
    }

    public String getUserToken() {
        return userToken;
    }

    public void setUserToken(String userToken) {
        this.userToken = userToken;
    }
}
public class Response {
    private ArrayList<ResponseMessage> messages;

    public Response() {}

    public Response(ArrayList<ResponseMessage> messages) {
        this.messages = messages;
    }

    public void addMessage(ResponseMessage message) {
        if(this.messages == null) {
            this.messages = new ArrayList<>();
        }

        this.messages.add(message);
    }
}