亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Spring 中使用自定義解析器返回 HTTP 狀態 BAD_REQUEST

在 Spring 中使用自定義解析器返回 HTTP 狀態 BAD_REQUEST

慕森王 2023-03-09 15:32:32
我正在使用Spring Boot 1.5.15開發 REST API 。我已經實施了一個客戶HandlerMethodArgumentResolver來映射 HTTP 標頭。具體來說,我分配了 HTTP header 的值Some-Header,刪除了前綴“XXX”。首先,我定義了一個自定義注解。@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.PARAMETER)public @interface SomeHeader {}然后,我實現了一個自定義解析器。public class SomeHeaderArgumentResolver implements HandlerMethodArgumentResolver {    @Override    public boolean supportsParameter(MethodParameter parameter) {        return parameter.getParameterAnnotation(SomeHeader.class) != null;    }    @Override    public Object resolveArgument(MethodParameter parameter,                                  ModelAndViewContainer mavContainer,                                  NativeWebRequest webRequest,                                  WebDataBinderFactory binderFactory) {        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();        final String headerValue = request.getHeader("Some-Header");        return headerValue.replace("XXX ", "");    }}最后,我讓 Spring 知道配置類中的解析器。@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {    @Override    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {        argumentResolvers.add(new SomeHeaderArgumentResolver());    }}現在,我可以在我需要的任何控制器中使用以下映射。@PostMapping("/some/paath")public void someMethod(@SomeHeader String someHeaderValue) {   // Method body...}但是,Some-Header信息對我來說是強制性的。我希望如果它不存在,Spring 會向調用者返回 400 Bad Request 響應。這與我使用注釋可以獲得的行為相同@RequestHeader("Some-Header")。我可以復制相同的行為嗎?可能,我不想使用專用的控制器建議。
查看完整描述

3 回答

?
拉風的咖菲貓

TA貢獻1995條經驗 獲得超2個贊

您可以為任何情況聲明自己的異常,并在控制器中設置 ExceptionHandler 以返回正確的 http-status。


@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler({SameHeaderException.class})

public Object onSameHeaderException(SameHeaderException e) {

    return ImmutableMap.of("reason", e.getMessage());

}

因此,如果標頭不存在,您可以拋出此異常:


if (someHeaderValue == null) { throw new SameHeaderException(); }


查看完整回答
反對 回復 2023-03-09
?
茅侃侃

TA貢獻1842條經驗 獲得超21個贊

RequestHeaderMethodArgumentResolver如果您看到which is used for的實現,您將看到抽象類方法@RequestHeader的重寫實現,如下所示:handleMissingValueAbstractNamedValueMethodArgumentResolver


@Override

protected void handleMissingValue(String name, MethodParameter parameter) throws ServletRequestBindingException {

        throw new ServletRequestBindingException("Missing request header '" + name +

                "' for method parameter of type " + parameter.getNestedParameterType().getSimpleName());

}

該handleMissingValue方法用于resolveArgument的方法中AbstractNamedValueMethodArgumentResolver,它RequestHeaderMethodArgumentResolver根據某些條件進行擴展。因此,當標頭不存在并ServletRequestBindingException拋出時,SpringDefaultHandlerExceptionResolver將處理該問題并發送400響應。


這就是驗證在@RequestHeader. resolveArgument所以你可以在你的類的方法中實現類似的東西,SomeHeaderArgumentResolver如下所示:


public class SomeHeaderArgumentResolver implements HandlerMethodArgumentResolver {

    @Override

    public boolean supportsParameter(MethodParameter parameter) {

        return parameter.getParameterAnnotation(SomeHeader.class) != null;

    }


    @Override

    public Object resolveArgument(MethodParameter parameter,

                                  ModelAndViewContainer mavContainer,

                                  NativeWebRequest webRequest,

                                  WebDataBinderFactory binderFactory) {

        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();

        final String headerValue = request.getHeader("Some-Header");

        if(headerValue != null){

           return headerValue.replace("XXX ", "");

        } else {

           //handle scenario if header absent with ServletRequestBindingException

        }

       }

    }


查看完整回答
反對 回復 2023-03-09
?
富國滬深

TA貢獻1790條經驗 獲得超9個贊

我明白了擴展哪個類是讓 Spring 發揮魔力的正確類。


RequestHeaderMethodArgumentResolverSpring 用來解析 Java 對象中的 HTTP 標頭值的類擴展了抽象類AbstractNamedValueMethodArgumentResolver。此類允許您使用createNamedValueInfo方法指定標頭值是否具有某些默認值。


所以,它遵循代碼。


public class SomeHeaderArgumentResolver extends AbstractNamedValueMethodArgumentResolver {

    @Override

    protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {

        // The second parameter specifies if the value is required, 

        // and the third if there is some default value.

        return new NamedValueInfo("", true, null);

    }


    @Override

    protected Object resolveName(String name, 

                                 MethodParameter parameter, 

                                 NativeWebRequest request) {

        final String headerValue = request.getHeader("Some-Value");

        if (StringUtils.isEmpty(headerValue)) {

            // Returning null tells Spring that there is no value for the parameter

            return null;

        }

        return headerValue.replace("XXX ", "");

    }


    @Override

    public boolean supportsParameter(MethodParameter parameter) {

        return (parameter.hasParameterAnnotation(SomeHeader.class) &&

                !Map.class.isAssignableFrom(

                    parameter.nestedIfOptional().getNestedParameterType()));

    }

}

我唯一不喜歡的是我正在使用為處理命名值而開發的結構,但我沒有命名值。


希望能幫助到你。


查看完整回答
反對 回復 2023-03-09
  • 3 回答
  • 0 關注
  • 242 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號