Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Last active December 25, 2018 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gakuzzzz/b16bb0e59782fb677273815a95bdfb77 to your computer and use it in GitHub Desktop.
Save gakuzzzz/b16bb0e59782fb677273815a95bdfb77 to your computer and use it in GitHub Desktop.
Spring で 値クラス変換

やりたい事

  • 以下みたいな ID<T>Name<T> みたいな値っぽいクラスのインスタンスを Controller の引数として受け取りたい。
  • ID<T> みたいなクラスは随時増えるので、増えるたびに Converter まで作るのを避けるために AbstractAtomConverterFactory を定義して一度で済ませたい。
  • ConverterFactory どうやって書けばいいのん?

ソース

値っぽいクラス

package jp.t2v;

public class ID<T> extends ComparableAbstractAtom<Integer, ID<T>> {
    private ID(final Integer value) {
        super(value);
    }

    public static <U> ID<U> of(final Integer value) {
        if (value <= 0) throw new IllegalArgumentException("value should be positive. " + value);
        return new ID<>(value);
    }

    private static final ID<Object> NOT_ASSIGNED = new ID<>(-1);

    @SuppressWarnings("unchecked")
    public static <U> ID<U> notAssigned() {
        return (ID<U>) NOT_ASSIGNED;
    }
}

package jp.t2v;

public class Name<T> extends ComparableAbstractAtom<String, Name<T>> {
    private Name(String value) {
        super(value);
    }

    public static <U> Name<U> of(final String value) {
        return new Name<>(value);
    }
}

package jp.t2v;

import java.io.Serializable;
import java.util.Objects;

public abstract class AbstractAtom<T extends Serializable> implements Serializable {

    private static final long serialVersionUID = 1;

    protected final T value;

    protected AbstractAtom(final T value) {
        Objects.requireNonNull(value, "value must be non-null");
        this.value = value;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (!(o instanceof AbstractAtom)) return false;
        AbstractAtom<?> that = (AbstractAtom<?>) o;
        return that.canEqual(this) && value.equals(that.value);
    }

    @Override
    public int hashCode() {
        return Objects.hash(value);
    }

    protected boolean canEqual(final AbstractAtom<?> self) {
        return getClass().equals(self.getClass());
    }

    public T getValue() {
        return value;
    }
}

package jp.t2v;

import java.io.Serializable;

public abstract class ComparableAbstractAtom<T extends Serializable & Comparable<? super T>, REPR extends ComparableAbstractAtom<T, REPR>>
        extends AbstractAtom<T> implements Comparable<REPR> {

    protected ComparableAbstractAtom(final T value) {
        super(value);
    }

    @Override
    public int compareTo(REPR o) {
        return this.value.compareTo(o.value);
    }
}

Controller

package jp.t2v;

import jp.t2v.User;
import jp.t2v.ID;
import jp.t2v.Organization;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/rest/v1.0/idtest")
public class IdTestResource {

    @RequestMapping("/orgs/{organizationId}/users/{userId}")
    public ResponseEntity<String> test(
        @PathVariable ID<Organization> organizationId,
        @PathVariable ID<User> userId
    ) {
        return ResponseEntity.ok("Okey-Dokey");
    }

}

Configuration

package jp.t2v;

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;


@Configuration
public class FormatterConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        ???
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        ???
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment