0

To decode url-arguments to color I use this HttpMessageConverter:

public class ColorHttpMessageConverter implements HttpMessageConverter<Color> {

    @Override
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return clazz == Color.class;
    }

    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return clazz == Color.class;
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return Collections.singletonList(MediaType.ALL);
    }

    @Override
    public Color read(Class<? extends Color> clazz, HttpInputMessage inputMessage)
            throws IOException, HttpMessageNotReadableException {
        byte[] buff = new byte[6];
        if (inputMessage.getBody().read(buff) != buff.length) {
            throw new HttpMessageNotReadableException("Must read 6 bytes.");
        }
        String c = new String(buff);
        return Color.decode("#" + c);
    }

    @Override
    public void write(Color t, MediaType contentType, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
        outputMessage.getBody().write(Integer.toHexString(t.getRGB()).substring(2).getBytes());
    }

}

Then I write a rest-controller having this mapping:

@Transactional
@RequestMapping("a.jpg")
public ResponseEntity<BufferedImage> getA(Color textcolor) throws IOException {

I call the url http://localhost:8080/myapp/rest/a.jpg?textcolor=ffffff but i get only this in console:

No primary or default constructor found for class java.awt.Color

Any ideas?

Grim
  • 1,938
  • 10
  • 56
  • 123
  • You should write a `Converter` and not an `HttpMessageConverter` and register it appropriatly. – M. Deinum Jun 12 '19 at 11:08
  • @M.Deinum I tried HttpMessageConverter and beans.Converter. The second did not work because the `@ConstructorProperties` is strict http-request-parameter-name bound. – Grim Jun 12 '19 at 11:10
  • YOu need a `Converter` as mentioned. The `HttpMessageConverter` is for something else. Why would you need `@ConstructorProperties`? – M. Deinum Jun 12 '19 at 11:12

1 Answers1

0

The HttpMessageConverter serves a whole different purpose, it is for translating the body into something else (or vice versa). What you want is a Converter<String, Color> and vice-versa, as you want to convert a request parameter and not the body to a Color.

public class StringToColorConverter implements Converter<String, Color> {

  public Color convert(String color) {
    return Color.decode("#" + color);
  }

}

and the other way

public class ColorToStringConverter implements Converter<Color,String> {

  public String convert(Color color) {
    return Integer.toHexString(color.getRGB()).substring(2);
  }

}

Now you can register them with a WebMvcConfigurer

@Configuration
public class MyWebConfigurer implements WebMvcConfigurer {

  public void addFormatters(FormatterRegistry registry) {
    registry.addConverter(new StringToColorConverter()):
    registry.addConverter(new ColorToStringConverter()):
  }

}

Now the converter should be used when that method argument with type Color is detected.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224