Spring doesn't initialize autowired DAO bean in service under XML-RPC controller

521 views Asked by At

guys. I have one question for you. I am implementing the login application that has XML-RPC controller for resolving requests and service (implements Spring Security UserDetails Service) for login implementing. The data for user login is stored in embedded mongodb database with the DAO accessing to it. So when I login, service with the help of dao gets to the database for users. Hovewer, in the moment of calling the service the DAO is not initialized (is null). What am I doing wrong? My controller class:

@Controller
public class XmlRpcController {
private XmlRpcServletServer server;

@Autowired
private UserService userService;

@PostConstruct
public void init() throws XmlRpcException {
    try {
        System.out.println("Starting the server on port 8090");
        XmlRpcServerConfigImpl config= new XmlRpcServerConfigImpl();

        server=new XmlRpcServletServer();
        server.setConfig(config);

        PropertyHandlerMapping xmlRpcHandlerMapping=new PropertyHandlerMapping();
        xmlRpcHandlerMapping.load(Thread.currentThread().getContextClassLoader(),"xmlrpc.properties");
        server.setHandlerMapping(xmlRpcHandlerMapping);
        System.out.println("The server started successfully.");

    } catch (Exception e) {
        System.err.println("Server Error: " + e);
        throw new XmlRpcException(e.getMessage());
    }
}

@RequestMapping("xmlrpc")
public  void serve(HttpServletRequest request, HttpServletResponse response) throws XmlRpcException {
    try {
        server.execute(request,response);
    } catch (Exception e) {
        throw new XmlRpcException(e.getMessage(), e);
    }
}
}

W xmlrpc.properties the service is defined for implementing requests:

service=org.vkalashnykov.service.UserService

Service:

@Service
public class UserService implements UserDetailsService{
    @Autowired
    private UserDAO userDAO;

@Override
    public UserDetails loadUserByUsername(@NotNull String username) throws UsernameNotFoundException {
        return userDAO.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("user "+username+ " was not found"));  // Here the userDAO is null
    }

    public String login(@NotNull String username, @NotNull String password){
        User user=(User)loadUserByUsername(username);
        if (user!=null && user.getPassword().equals(new BCryptPasswordEncoder().encode(password)))
            return Statuses.SUCCESS.name();
        else
            return Statuses.ERROR.name();
    }
}

DAO:

 @Component
public class UserDAO{

@Autowired
MongoTemplate mongoTemplate;

public Optional<User> findByUsername(@NotNull String username){
    return Optional.ofNullable(mongoTemplate.findOne(
            query(
                    where(UserField.USER_NAME.getField()).is(username)),
                    User.class));
}

public void save(User user){
    mongoTemplate.save(user);
}

}

Spring Security configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserService userService;

@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
    return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/xmlrpc").permitAll()
            .and()
            .csrf().disable();
}

@Autowired
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userService).passwordEncoder(getBCryptPasswordEncoder());
}
}

On client side there is an application that sends username and password to server for login:

@FXML
private TextField login;

@FXML
private TextField password;

private  String configuration="xmlrpc";

private final String serverUrl="http://localhost:8090/xmlrpc";

private final XmlRpcClient xmlRpcClient=new XmlRpcClient();

public Controller() throws Exception {
    final XmlRpcClientConfigImpl config=new XmlRpcClientConfigImpl();
    try {
        System.out.println("Trying connect to server "+serverUrl);
        config.setServerURL(new URL(serverUrl));
    } catch (MalformedURLException e) {
        System.err.println("Server "+serverUrl+" not found.");
        e.printStackTrace();
        errorLabel.setText("Server not found.");
        throw new Exception("Server not found.");
    }
    xmlRpcClient.setConfig(config);
    System.out.println("Connected to server: "+serverUrl);
}
1

There are 1 answers

0
Viktor Kalashnykov On

I changed the controller's configuration for Apache XML-RPC framework in next way:

@Controller
public class XmlRpcController {
    private XmlRpcServletServer server;
  @Autowired
  UserService userService;

  @PostConstruct
  public void init() throws XmlRpcException {
    try {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        System.out.println("Starting the server on port 8090");
        XmlRpcServerConfigImpl config= new XmlRpcServerConfigImpl();

        server=new XmlRpcServletServer();
        server.setConfig(config);

        PropertyHandlerMapping xmlRpcHandlerMapping=new PropertyHandlerMapping();
        xmlRpcHandlerMapping.setRequestProcessorFactoryFactory(pClass->pRequest->userService);
        xmlRpcHandlerMapping.addHandler(UserService.class.getSimpleName(),UserService.class);
        XmlRpcSystemImpl.addSystemHandler(xmlRpcHandlerMapping);
        server.setHandlerMapping(xmlRpcHandlerMapping);
        System.out.println("The server started successfully.");

    } catch (Exception e) {
        System.err.println("Server Error: " + e);
        throw new XmlRpcException(e.getMessage());
    }
  }
}

Seems to work, now the DAO is fully initializied. Thank you.