HandlerMethodArgumentResolver(パラメータ解析器)の役割+使用事例
4469 ワード
前言
今日、プロジェクトをしている間に、パラメータ解析に関するHandlerMethodArgumentResolverの使用に関する疑問に遭遇しました.初心者の私はここで皆さんと交流して記録したいと思います.これから発車・・・
本文
まず、このインタフェース、HandlerMethodArgumentResolverを認識してみましょう.
このインタフェースには、supportsParameterとresolveArgumentの2つの方法があります.
メソッドsupportsParameterはよく理解され、戻り値はbooleanタイプであり、Controllerレイヤのパラメータが条件を満たすかどうかを判断し、条件を満たすとresolveArgumentメソッドを実行し、満たさないとスキップする役割を果たす.
resolveArgumentメソッドは、supportsParameterメソッドがtrueを返す場合にのみ呼び出されます.いくつかのビジネスを処理するために、戻り値をControllerレイヤのこのパラメータに割り当てます.
したがって,HandlerMethodArgumentResolverをパラメータ解析器として理解することができ,クラス実装HandlerMethodArgumentResolverインタフェースを書くことでController層におけるメソッドパラメータの修正を実現することができる.
プロジェクトコードの例
パラメータ解析器が使用されていない場合のControllerコントローラ:
皆さんよく見てくださいto_loginメソッドのこの2つのパラメータcookieTokenとparamTokenを、メソッドボディをもう一度よく見てみましょう.この2つのパラメータとメソッドボディの文コードは、クッキーまたはrequestのtokenという変数によってユーザーuserの情報をクエリーするためであることがわかります.
しかし、皆さんは発見していません.この方法は、簡単なこの小さな機能のために、こんなに多くのコードを書いています.ちょっと太りすぎじゃないですか?また、ユーザーuserという情報変数を使用する他の方法はありますか?
はい、この時、HandlerMethodArgumentResolverインタフェースを使用して小さな最適化を行うことができます.
HandlerMethodArgumentResolver解析を使用した後:
クラス実装を書くHandlerMethodArgumentResolverインタフェース
私たちが作成したこのクラスをプロファイルに登録します.
最後に、私たちの制御クラスはこのように書くことができます.
今日、プロジェクトをしている間に、パラメータ解析に関するHandlerMethodArgumentResolverの使用に関する疑問に遭遇しました.初心者の私はここで皆さんと交流して記録したいと思います.これから発車・・・
本文
まず、このインタフェース、HandlerMethodArgumentResolverを認識してみましょう.
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter var1);
Object resolveArgument(MethodParameter var1, ModelAndViewContainer var2, NativeWebRequest var3, WebDataBinderFactory var4) throws Exception;
}
このインタフェースには、supportsParameterとresolveArgumentの2つの方法があります.
メソッドsupportsParameterはよく理解され、戻り値はbooleanタイプであり、Controllerレイヤのパラメータが条件を満たすかどうかを判断し、条件を満たすとresolveArgumentメソッドを実行し、満たさないとスキップする役割を果たす.
resolveArgumentメソッドは、supportsParameterメソッドがtrueを返す場合にのみ呼び出されます.いくつかのビジネスを処理するために、戻り値をControllerレイヤのこのパラメータに割り当てます.
したがって,HandlerMethodArgumentResolverをパラメータ解析器として理解することができ,クラス実装HandlerMethodArgumentResolverインタフェースを書くことでController層におけるメソッドパラメータの修正を実現することができる.
プロジェクトコードの例
パラメータ解析器が使用されていない場合のControllerコントローラ:
@Controller
@RequestMapping("/goods")
public class GoodsController {
private static Logger logger = LoggerFactory.getLogger(GoodsController.class);
@Autowired
UserService userService;
@RequestMapping("/to_list")
public String to_login(Model model,HttpServletResponse response,
@CookieValue(value=UserService.TOKEN,required = false)String cookieToken,
@RequestParam(value = UserService.TOKEN,required = false) String paramToken) {
if(StringUtils.isEmpty(cookieToken)&&StringUtils.isEmpty(paramToken)){
return "login";
}
String token = StringUtils.isEmpty(cookieToken) ? paramToken : cookieToken;
User user=userService.getByToken(response,token);
logger.info(user.toString());
model.addAttribute("user",user);
return "goods_list";
}
}
皆さんよく見てくださいto_loginメソッドのこの2つのパラメータcookieTokenとparamTokenを、メソッドボディをもう一度よく見てみましょう.この2つのパラメータとメソッドボディの文コードは、クッキーまたはrequestのtokenという変数によってユーザーuserの情報をクエリーするためであることがわかります.
しかし、皆さんは発見していません.この方法は、簡単なこの小さな機能のために、こんなに多くのコードを書いています.ちょっと太りすぎじゃないですか?また、ユーザーuserという情報変数を使用する他の方法はありますか?
はい、この時、HandlerMethodArgumentResolverインタフェースを使用して小さな最適化を行うことができます.
HandlerMethodArgumentResolver解析を使用した後:
クラス実装を書くHandlerMethodArgumentResolverインタフェース
@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
MiaoshaUserService userService;
public boolean supportsParameter(MethodParameter parameter) {
Class> clazz = parameter.getParameterType();
return clazz==MiaoshaUser.class;
}
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);
String cookieToken = getCookieValue(request, MiaoshaUserService.COOKI_NAME_TOKEN);
if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
return null;
}
String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
return userService.getByToken(response, token);
}
private String getCookieValue(HttpServletRequest request, String cookiName) {
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
if(cookie.getName().equals(cookiName)) {
return cookie.getValue();
}
}
return null;
}
}
私たちが作成したこのクラスをプロファイルに登録します.
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
@Autowired
UserArgumentResolver userArgumentResolver;
@Override
public void addArgumentResolvers(List argumentResolvers) {
argumentResolvers.add(userArgumentResolver);
}
}
最後に、私たちの制御クラスはこのように書くことができます.
@RequestMapping("/to_list")
public String list(Model model,MiaoshaUser user) {
model.addAttribute("user", user);
//
List goodsList = goodsService.listGoodsVo();
model.addAttribute("goodsList", goodsList);
return "goods_list";
}