Есть ли способ заставить @InitBinder работать с параметром карты или перезаписать пружину по умолчанию HandlerMethodArgumentResolver? - PullRequest
0 голосов
/ 03 января 2019

Я использую карту для принятия параметра, я отправляю параметр типа Integer, я получаю строку в Map, я хочу использовать @initbinder для преобразования значения в Integer, но мой код не работает.и если я не напишу @RequestParam, карта будет нулевой.Что я должен делать?Любые советы благодарны.

Я только что отладил с исходным кодом Spring, я нахожу способ сделать это:

1. @ Карта запроса RequestParam будет решена с помощью RequestParamMapMethodArgumentResolver 2. Я пишу мойбоб, чтобы перезаписать его, чтобы я мог изменить значение карты в целое число.и я сделал это

но, весной найти MethodArgumentResolvers по порядку, как только он найдет RequestParamMapMethodArgumentResolver, цикл прервется, поэтому мой компонент никогда не будет работать.

так есть ли способ перезаписать метод по умолчанию MethodArgumentResolver или удалить его?

public class MapEditor extends PropertyEditorSupport {

@Override
public void setAsText(String text) throws IllegalArgumentException {
    System.out.println("+++++++++++++++++++++++++++++++++++");
    if(text.matches("\\d+")){
        super.setValue(Integer.parseInt(text));
    }
    super.setAsText(text);
}

@Override
public String getAsText() {
    System.out.println("======================================");
    return super.getAsText();
}
}

@InitBinder
public void map(WebDataBinder binder){
    binder.registerCustomEditor(Map.class,new MapEditor());
    binder.registerCustomEditor(Date.class,new DateEditor());
}

    @GetMapping("/loadMessageList2")
public String loadMessageList2(@RequestParam Map<String,Object> map){
    return "hello world" + map.get("start");
}

---------------- после отладки -------------------------

public class MyRequestParamMapMethodArgumentResolver extends 
RequestParamMapMethodArgumentResolver {
    @Override
    public Object resolveArgument(MethodParameter parameter, @Nullable 
    ModelAndViewContainer mavContainer,
                              NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
    Map map = (Map) super.resolveArgument(parameter,mavContainer,webRequest, binderFactory);
    Set<Map.Entry> set = map.entrySet();
    for (Map.Entry entry : set) {
        if(entry.getValue().toString().matches("\\d+")){
            entry.setValue(Integer.parseInt(entry.getValue().toString()));
        }
    }
    return map;
}
}

и зарегистрируйте его

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> 
argumentResolvers) {
        argumentResolvers.add(new MyRequestParamMapMethodArgumentResolver());
    }
}

1 Ответ

0 голосов
/ 07 января 2019

Прежде всего, карта параметров должна иметь @RequestParam, поэтому она может быть решена с помощью RequestParamMapMethodArgumentResolver. этот преобразователь выполнит большую часть работы, преобразовав параметр в карту. Поэтому моя работа состоит в том, чтобы просмотреть все значения карты и посмотреть, является ли значение числом, и изменить его на Integer. Вот мое окончательное решение Напишите мои экстенты распознавателя RequestParamMapMethodArgumentResolver:

public class MyRequestParamMapMethodArgumentResolver extends 
RequestParamMapMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(MyMap.class) != null;
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, @Nullable 
ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, @Nullable 
WebDataBinderFactory binderFactory) throws Exception {
        Map map = (Map) super.resolveArgument(parameter,mavContainer,webRequest, 
binderFactory);
        Set<Map.Entry> set = map.entrySet();
        for (Map.Entry entry : set) {
            if(entry.getValue().toString().matches("\\d+")){
                entry.setValue(Integer.parseInt(entry.getValue().toString()));
            }
        }
        return map;
    }
}

зарегистрируйте его с пружиной

    @Configuration
    public class MyRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
        @Override
        public void afterPropertiesSet() {
            super.afterPropertiesSet();
            List<HandlerMethodArgumentResolver> argumentResolvers = getArgumentResolvers();
            if (argumentResolvers != null) {
                List<HandlerMethodArgumentResolver> argumentResolversort = new ArrayList<>();
                boolean flag = false;
                for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) {
                    if (argumentResolver instanceof MyRequestParamMapMethodArgumentResolver) {
                        argumentResolversort.add(argumentResolver);
                        argumentResolvers.remove(argumentResolver);
                        flag = true;
                        break;
                    }
                }
                if(!flag){
                    argumentResolversort.add(new MyRequestParamMapMethodArgumentResolver());
                }
                argumentResolversort.addAll(argumentResolvers);
                setArgumentResolvers(argumentResolversort);
            }
        }
    }

не очень изящно, но по причине. желаю, чтобы кто-то мог найти лучший путь. желаю, чтобы это помогло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...