Home > Software engineering >  Is it possible to pass custom object into SpringBoot's endpoint?
Is it possible to pass custom object into SpringBoot's endpoint?

Time:11-05

I have a SpringBoot project and in an every endpoint's the first call is parsing a request header into a POJO object. making sure required headers are set. Is it possible "to teach" SpringBoot to be able to provide custom object in endpoints?

class CommonHeader {

    private String callerId;
    private String systemId;
    ....

    public static CommonHeader parseCommonHeader(Map<String, String> map) {
        CommonHeader header = new CommonHeader();
        header.setCallerId(map.get("x-caller-id"));
        .....
        return header;
    }
}

@Path("/columnConfigs")
Response getColumnConfig(@RequestHeader Map<String, String> headers) {
    CommonHeader commonHeader = parseCommonHeader(headers);
    ....
}

@Path("/other")
Response getColumnConfig(@RequestHeader Map<String, String> headers) {
    CommonHeader commonHeader = parseCommonHeader(headers);
    ....
}


I would like to be able to simplify the following code into:


@Path("/columnConfigs")
Response getColumnConfig(CommonHeader commonHeader) {
    ....
}

@Path("/other")
Response getColumnConfig(CommonHeader commonHeader) {
    ....
}

CodePudding user response:

Define CommonHeader to extend Map<String, String>:

@RequestHeader
public interface CommonHeader extends Map<String, String> {
}

CodePudding user response:

I was looking for some solution for this, that is, bind headers to an object of our definition. I found a good technique here: Using Custom Data Binders in SpringMVC

What you have to do in a nutshell are these, apart from the already created CommonHeader class:

  1. Define an annotation, say @MyHeaders (with @Retention( RUNTIME ) and @Target( PARAMETER ))
@Retention( RUNTIME )
@Target( PARAMETER )
public @interface MyHeaders {}
  1. Create an implementation of HandlerMethodArgumentResolver, say MyHeadersResolver. This will map the headers from the request into an instance of CommonHeader and return it.
@Override
    public boolean supportsParameter( MethodParameter methodParameter ){
        return methodParameter.getParameterAnnotation( MyHeaders.class ) != null;
    }

    @Override
    public Object resolveArgument( MethodParameter methodParameter, ModelAndViewContainer mavc, NativeWebRequest req, WebDataBinderFactory wdbf ) throws Exception{
        HttpServletRequest request = (HttpServletRequest) req.getNativeRequest();
        
        CommonHeader h = new CommonHeader();
        Collections.list( request.getHeaderNames() ).forEach( header -> {
            switch( header.toLowerCase() ) {
                //Set values into CommonHeader instance
            }
        });
        
        return h;
    }
  1. Declare this to SpringMVC as an argument resolver in a class that implements WebMvcConfigurer, like this:
@Override
public void addArgumentResolvers( List<HandlerMethodArgumentResolver> resolvers ) {
    resolvers.add( new MyHeadersResolver() );
}
  1. Your controller method signature will now look like this:
Response getColumnConfig( @MyHeaders CommonHeader commonHeader )
  • Related