All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.is24.common.web.Base64DecodingArgumentResolver Maven / Gradle / Ivy

package de.is24.common.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;


public class Base64DecodingArgumentResolver implements HandlerMethodArgumentResolver {
  private static final Logger LOGGER = LoggerFactory.getLogger(Base64DecodingArgumentResolver.class);
  public static final String STANDARD_ENCODING = StandardCharsets.ISO_8859_1.name();

  private final String encoding;

  public Base64DecodingArgumentResolver() {
    this.encoding = STANDARD_ENCODING;
  }

  public Base64DecodingArgumentResolver(String encoding) {
    this.encoding = encoding;
  }

  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    return findMethodAnnotation(DecodedUrl.class, parameter) != null;
  }

  @Override
  public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
    String parameterName = parameter.getParameterName();
    String parameterPayload = webRequest.getParameter(parameterName);
    if (parameterPayload == null) {
      DecodedUrl methodAnnotation = findMethodAnnotation(DecodedUrl.class, parameter);
      if (methodAnnotation.required()) {
        throw new MissingServletRequestParameterException("Missing parameter {}.", parameterName);
      } else {
        return null;
      }
    }
    return parseUrl(parameterPayload);
  }

  private URL parseUrl(String possiblyEncodedUrl) throws ServletRequestBindingException {
    LOGGER.debug("Decoding possible encoded url. Payload: {}", possiblyEncodedUrl);
    try {
      return new URL(possiblyEncodedUrl);
    } catch (MalformedURLException e) {
      return decodeUrl(possiblyEncodedUrl);
    }
  }

  private URL decodeUrl(String possiblyEncodedUrl) throws ServletRequestBindingException {
    LOGGER.debug("Try to decode URL with URL decoder.");
    try {
      String decoded = URLDecoder.decode(possiblyEncodedUrl, encoding);
      return new URL(decoded);
    } catch (MalformedURLException | UnsupportedEncodingException e) {
      return decodeBase64Url(possiblyEncodedUrl);
    }
  }

  private URL decodeBase64Url(String possiblyEncodedUrl) throws ServletRequestBindingException {
    LOGGER.debug("Try to decode url with Base64 decoder.");
    try {
      byte[] decodedUrl = Base64.getDecoder().decode(possiblyEncodedUrl);
      return new URL(new String(decodedUrl));
    } catch (IllegalArgumentException | MalformedURLException iae) {
      LOGGER.debug("Failed to decode URL parameter.");
      throw new ServletRequestBindingException("Failed to decode URL parameter!");
    }
  }

  private  T findMethodAnnotation(Class annotationClass, MethodParameter parameter) {
    T annotation = parameter.getParameterAnnotation(annotationClass);
    return (annotation != null) ? annotation : searchForAnnotation(annotationClass, parameter);
  }

  private  T searchForAnnotation(Class annotationClass, MethodParameter parameter) {
    T annotation;
    Annotation[] annotationsToSearch = parameter.getParameterAnnotations();
    for (Annotation toSearch : annotationsToSearch) {
      annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), annotationClass);
      if (annotation != null) {
        return annotation;
      }
    }
    return null;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy