【问题标题】:Spring doesn't initialize autowired DAO bean in service under XML-RPC controllerSpring 不会在 XML-RPC 控制器下初始化服务中的自动装配 DAO bean
【发布时间】:2017-05-10 10:49:05
【问题描述】:

伙计们。我有一个问题要问你。我正在实现登录应用程序,该应用程序具有用于解析请求和服务(实现 Spring Security UserDetails 服务)的 XML-RPC 控制器以实现登录。用户登录的数据存储在嵌入式 mongodb 数据库中,DAO 可以访问它。 因此,当我登录时,在 dao 的帮助下,服务会为用户访问数据库。然而,在调用服务的那一刻,DAO 没有被初始化(为空)。我究竟做错了什么? 我的控制器类:

@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 服务被定义用于实现请求:

service=org.vkalashnykov.service.UserService

服务:

@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();
    }
}

道:

 @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 安全配置:

@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());
}
}

在客户端有一个应用程序将用户名和密码发送到服务器进行登录:

@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);
}

【问题讨论】:

  • 所以你期望一个不由spring管理的类实例被spring注入和控制......你的RPC框架控制的是实例而不是Spring,所以不会自动装配任何东西。
  • 有没有办法使用 RPC 管理 Spring bean?

标签: mongodb spring-boot spring-security xml-rpc xmlrpcclient


【解决方案1】:

我通过以下方式更改了 Apache XML-RPC 框架的控制器配置:

@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());
    }
  }
}

似乎可以工作,现在 DAO 已完全初始化。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 2018-04-01
    • 2021-12-07
    • 1970-01-01
    • 2015-12-23
    • 2014-11-08
    • 1970-01-01
    相关资源
    最近更新 更多