存储和访问对象"外部"在Spring Boot中

时间:2018-06-03 14:15:33

标签: java spring-boot

我有一个HandlerInteceptor:

public class RequestInterceptor implements HandlerInterceptor {

@Autowired
private AddressService addressservice

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String ip_address = request.getRemoteAddr();
    addressservice.storeIp_address(ip_address);
    return true;
}
}

对象:

public class IpAddress {
private String ip_address;

public String getIp_address() {
    return ip_address;
}

public IpAddress setIp_address(String ip_address) {
    this.ip_address = ip_address;
    return this;
}
}

服务:

@Service
public class AddressService {
private IpAddress ipAddress;

public void storeIpAddress(String ip_address){
    ipAddress.setIp_address(ip_address);
}

public void getIpAddress(){
    ipAddress.getIp_address();
}}

现在如何将IP地址保存在另一个对象中,以便下次请求被截获时我可以访问它?我尝试过使用@Service等,但我总是得到nullpointer异常。我无法理解Spring-Boot的工作原理。对我来说这似乎是火箭科学。

更新

@Service
public class AccessService {
    private Map<String, LocalDateTime> access = new HashMap<>();

    public Map getAccess() {
        return access;
    }

    public void addAccess(String ip_address, LocalDateTime date) {
        access.put(ip_address, date);
    }
}

拦截器:

public class RequestInterceptor implements HandlerInterceptor {

@Autowired
private AccessService accessService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(accessService.getAccess().values());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LocalDateTime datetime = LocalDateTime.now();
        accessService.addAccess(request.getRemoteAddr(), datetime);
        System.out.println(accessService.getAccess());
    }
}

我仍然得到Nullpointer Exceptions ..

UPDATE2 我终于成功了:

    public class RequestInterceptor implements HandlerInterceptor {

    private Map<String, LocalDateTime> access = new HashMap<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ip_address = request.getRemoteAddr();
        for (String key : access.keySet()){
            if (access.get(key).plusSeconds(5).isBefore(LocalDateTime.now())){
                access.remove(key);
            }
        }
        if (access.containsKey(ip_address) == true){
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        access.put(request.getRemoteAddr(), LocalDateTime.now());
    }
}

2 个答案:

答案 0 :(得分:0)

您可以通过将对象存储在会话范围中并在任何位置获取值来完成此操作。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyHandlerInterceptor());
    }
}

并使用getAttribute()下次使用它。

HttpSession session = request.getSession();
session.setAttribute("ip_address",ip_address);

答案 1 :(得分:0)

在您的服务类中,IpAddress类的对象未初始化。所以在setter方法中抛出空指针。

我应该也要求堆栈跟踪。我的错 !! :P

Okies .. !!

<强>解决方案:

@Service
public class AddressService {
private IpAddress ipAddress = new IpAddress();

public void storeIpAddress(String ip_address){
    ipAddress.setIp_address(ip_address);
}

public void getIpAddress(){
    ipAddress.getIp_address();
}}

<强>更新

这种方法的一个严重问题是,你会一次又一次得到同一个对象,因为POJO(如IpAddress)类必须始终是一个新的对象(除非需要)。

此外,您似乎过度使用服务模式。

我的意思是,它只是你POJO类中的一个String对象,所以你为什么要制作它的POJO。

** POJO:普通的旧Java对象。