成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

從原理層面掌握@SessionAttribute的使用【一起學(xué)Spring MVC】

ARGUS / 3411人閱讀

摘要:見(jiàn)名之意,它是處理器,也就是解析這個(gè)注解的核心。管理通過(guò)標(biāo)注了的特定會(huì)話(huà)屬性,存儲(chǔ)最終是委托了來(lái)實(shí)現(xiàn)。只會(huì)清楚注解放進(jìn)去的,并不清除放進(jìn)去的它的唯一實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)也簡(jiǎn)單。在更新時(shí),模型屬性與會(huì)話(huà)同步,如果缺少,還將添加屬性。

每篇一句
不是你當(dāng)上了火影大家就認(rèn)可你,而是大家都認(rèn)可你才能當(dāng)上火影
前言

該注解顧名思義,作用是將Model中的屬性同步到session會(huì)話(huà)當(dāng)中,方便在下一次請(qǐng)求中使用(比如重定向場(chǎng)景~)。
雖然說(shuō)Session的概念在當(dāng)下前后端完全分離的場(chǎng)景中已經(jīng)變得越來(lái)越弱化了,但是若為web開(kāi)發(fā)者來(lái)說(shuō),我仍舊強(qiáng)烈不建議各位扔掉這個(gè)知識(shí)點(diǎn),so我自然就建議大家能夠熟練使用@SessionAttribute來(lái)簡(jiǎn)化平時(shí)的開(kāi)發(fā),本文帶你入坑~

@SessionAttribute

這個(gè)注解只能標(biāo)注在類(lèi)上,用于在多個(gè)請(qǐng)求之間傳遞參數(shù),類(lèi)似于SessionAttribute。
但不完全一樣:一般來(lái)說(shuō)@SessionAttribute設(shè)置的參數(shù)只用于暫時(shí)的傳遞,而不是長(zhǎng)期的保存,長(zhǎng)期保存的數(shù)據(jù)還是要放到Session中。(比如重定向之間暫時(shí)傳值,用這個(gè)注解就很方便)

==官方解釋==:當(dāng)用@SessionAttribute標(biāo)注的Controller向其模型Model添加屬性時(shí),將根據(jù)該注解指定的名稱(chēng)/類(lèi)型檢查這些屬性,若匹配上了就順帶也會(huì)放進(jìn)Session里。匹配上的將一直放在Sesson中,直到你調(diào)用了SessionStatus.setComplete()方法就消失了~~~

// @since 2.5   它只能標(biāo)注在類(lèi)上
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {

    // 只有名稱(chēng)匹配上了的  Model上的屬性會(huì)向session里放置一份~~~
    @AliasFor("names")
    String[] value() default {};
    @AliasFor("value")
    String[] names() default {};

    // 也可以拿類(lèi)型來(lái)約束
    Class[] types() default {};
}

注意理解這句話(huà):用戶(hù)可以調(diào)用SessionStatus.setComplete來(lái)清除,這個(gè)方法只是清除SessionAttribute里的參數(shù),而不會(huì)應(yīng)用于Session中的參數(shù)。也就是說(shuō)使用API自己放進(jìn)Session內(nèi)和使用@SessionAttribute注解放進(jìn)去還是有些許差異的~

Demo Show

下面用一個(gè)比較簡(jiǎn)單的例子演示一下@SessionAttribute它的作用:

@Controller
@RequestMapping("/sessionattr/demo")
@SessionAttributes(value = {"book", "description"}, types = {Double.class})
public class RedirectController {

    @RequestMapping("/index")
    public String index(Model model, HttpSession httpSession) {
        model.addAttribute("book", "天龍八部");
        model.addAttribute("description", "我喬峰是個(gè)契丹人");
        model.addAttribute("price", new Double("1000.00"));

        // 通過(guò)Sesson API手動(dòng)放一個(gè)進(jìn)去
        httpSession.setAttribute("hero", "fsx");

        //跳轉(zhuǎn)之前將數(shù)據(jù)保存到Model中,因?yàn)樽⒔釦SessionAttribute中有,所以book和description應(yīng)該都會(huì)保存到SessionAttributes里(注意:不是session里)
        return "redirect:get";
    }

    // 關(guān)于@ModelAttribute 下文會(huì)講
    @RequestMapping("/get")
    public String get(@ModelAttribute("book") String book, ModelMap model, HttpSession httpSession, SessionStatus sessionStatus) {
        //可以從model中獲得book、description和price的參數(shù)
        System.out.println(model.get("book") + ";" + model.get("description") + ";" + model.get("price"));

        // 從sesson中也能拿到值
        System.out.println(httpSession.getAttribute("book"));
        System.out.println("API方式手動(dòng)放進(jìn)去的:" + httpSession.getAttribute("hero"));
        // 使用@ModelAttribute也能拿到值
        System.out.println(book);

        // 手動(dòng)清除SessionAttributes
        sessionStatus.setComplete();
        return "redirect:complete";
    }

    @RequestMapping("/complete")
    @ResponseBody
    public String complete(ModelMap modelMap, HttpSession httpSession) {
        //已經(jīng)被清除,無(wú)法獲取book的值
        System.out.println(modelMap.get("book"));
        System.out.println("API方式手動(dòng)放進(jìn)去的:" + httpSession.getAttribute("hero"));
        return "sessionAttribute";
    }

}

我們只需要訪問(wèn)入口請(qǐng)求/index就可以直接看到控制臺(tái)輸出如下:

天龍八部;我喬峰是個(gè)契丹人;1000.0
天龍八部
API方式手動(dòng)放進(jìn)去的:fsx
天龍八部
null
API方式手動(dòng)放進(jìn)去的:fsx

瀏覽器如下圖:

初識(shí)的小伙伴可以認(rèn)真的觀察本例,它佐證了我上面說(shuō)的理論知識(shí)。

@SessionAttribute注解設(shè)置的參數(shù)有3類(lèi)方式去使用它:

在視圖view中(比如jsp頁(yè)面等)通過(guò)request.getAttribute()session.getAttribute獲取

在后面請(qǐng)求返回的視圖view中通過(guò)session.getAttribute或者從model中獲取(這個(gè)也比較常用)

自動(dòng)將參數(shù)設(shè)置到后面請(qǐng)求所對(duì)應(yīng)處理器的Model類(lèi)型參數(shù)或者有@ModelAttribute注釋的參數(shù)里面(結(jié)合@ModelAttribute一起使用應(yīng)該是我們重點(diǎn)關(guān)注的)

通過(guò)示例知道了它的基本使用,下面從原理層面去分析它的執(zhí)行過(guò)程,實(shí)現(xiàn)真正的掌握它。

SessionAttributesHandler

見(jiàn)名之意,它是@SessionAttributes處理器,也就是解析這個(gè)注解的核心。管理通過(guò)@SessionAttributes標(biāo)注了的特定會(huì)話(huà)屬性,存儲(chǔ)最終是委托了SessionAttributeStore來(lái)實(shí)現(xiàn)。

// @since 3.1
public class SessionAttributesHandler {

    private final Set attributeNames = new HashSet<>();
    private final Set> attributeTypes = new HashSet<>();

    // 注意這個(gè)重要性:它是注解方式放入session和API方式放入session的關(guān)鍵(它只會(huì)記錄注解方式放進(jìn)去的session屬性~~)
    private final Set knownAttributeNames = Collections.newSetFromMap(new ConcurrentHashMap<>(4));
    // sessonAttr存儲(chǔ)器:它最終存儲(chǔ)到的是WebRequest的session域里面去(對(duì)httpSession是進(jìn)行了包裝的)
    // 因?yàn)橛蠾ebRequest的處理,所以達(dá)到我們上面看到的效果。complete只會(huì)清楚注解放進(jìn)去的,并不清除API放進(jìn)去的~~~
    // 它的唯一實(shí)現(xiàn)類(lèi)DefaultSessionAttributeStore實(shí)現(xiàn)也簡(jiǎn)單。(特點(diǎn):能夠制定特殊的前綴,這個(gè)有時(shí)候還是有用的)
    // 前綴attributeNamePrefix在構(gòu)造器里傳入進(jìn)來(lái)  默認(rèn)是“”
    private final SessionAttributeStore sessionAttributeStore;

    // 唯一的構(gòu)造器 handlerType:控制器類(lèi)型  SessionAttributeStore 是由調(diào)用者上層傳進(jìn)來(lái)的
    public SessionAttributesHandler(Class handlerType, SessionAttributeStore sessionAttributeStore) {
        Assert.notNull(sessionAttributeStore, "SessionAttributeStore may not be null");
        this.sessionAttributeStore = sessionAttributeStore;

        // 父類(lèi)上、接口上、注解上的注解標(biāo)注了這個(gè)注解都算
        SessionAttributes ann = AnnotatedElementUtils.findMergedAnnotation(handlerType, SessionAttributes.class);
        if (ann != null) {
            Collections.addAll(this.attributeNames, ann.names());
            Collections.addAll(this.attributeTypes, ann.types());
        }
        this.knownAttributeNames.addAll(this.attributeNames);
    }

    // 既沒(méi)有指定Name 也沒(méi)有指定type  這個(gè)注解標(biāo)上了也沒(méi)啥用
    public boolean hasSessionAttributes() {
        return (!this.attributeNames.isEmpty() || !this.attributeTypes.isEmpty());
    }

    // 看看指定的attributeName或者type是否在包含里面
    // 請(qǐng)注意:name和type都是或者的關(guān)系,只要有一個(gè)符合條件就成
    public boolean isHandlerSessionAttribute(String attributeName, Class attributeType) {
        Assert.notNull(attributeName, "Attribute name must not be null");
        if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) {
            this.knownAttributeNames.add(attributeName);
            return true;
        } else {
            return false;
        }
    }

    // 把a(bǔ)ttributes屬性們存儲(chǔ)起來(lái)  進(jìn)到WebRequest 里
    public void storeAttributes(WebRequest request, Map attributes) {
        attributes.forEach((name, value) -> {
            if (value != null && isHandlerSessionAttribute(name, value.getClass())) {
                this.sessionAttributeStore.storeAttribute(request, name, value);
            }
        });
    }

    // 檢索所有的屬性們  用的是knownAttributeNames哦~~~~
    // 也就是說(shuō)手動(dòng)API放進(jìn)Session的 此處不會(huì)被檢索出來(lái)的
    public Map retrieveAttributes(WebRequest request) {
        Map attributes = new HashMap<>();
        for (String name : this.knownAttributeNames) {
            Object value = this.sessionAttributeStore.retrieveAttribute(request, name);
            if (value != null) {
                attributes.put(name, value);
            }
        }
        return attributes;
    }

    // 同樣的 只會(huì)清除knownAttributeNames
    public void cleanupAttributes(WebRequest request) {
        for (String attributeName : this.knownAttributeNames) {
            this.sessionAttributeStore.cleanupAttribute(request, attributeName);
        }
    }


    // 對(duì)底層sessionAttributeStore的一個(gè)傳遞調(diào)用~~~~~
    // 畢竟可以拼比一下sessionAttributeStore的實(shí)現(xiàn)~~~~
    @Nullable
    Object retrieveAttribute(WebRequest request, String attributeName) {
        return this.sessionAttributeStore.retrieveAttribute(request, attributeName);
    }
}

這個(gè)類(lèi)是對(duì)SessionAttribute這些屬性的核心處理能力:包括了所謂的增刪改查。因?yàn)橐M(jìn)一步理解到它的原理,所以要說(shuō)到它的處理入口,那就要來(lái)到ModelFactory了~

ModelFactory

Spring MVC對(duì)@SessionAttribute的處理操作入口,是在ModelFactory.initModel()方法里會(huì)對(duì)@SessionAttribute的注解進(jìn)行解析、處理,然后方法完成之后也會(huì)對(duì)它進(jìn)行屬性同步。

ModelFactory是用來(lái)維護(hù)Model的,具體包含兩個(gè)功能:

處理器執(zhí)行前,初始化Model

處理器執(zhí)行后,將Model中相應(yīng)的參數(shù)同步更新到SessionAttributes中(不是全量,而是符合條件的那些)

// @since 3.1
public final class ModelFactory {
    // ModelMethod它是一個(gè)私有內(nèi)部類(lèi),持有InvocableHandlerMethod的引用  和方法的dependencies依賴(lài)們
    private final List modelMethods = new ArrayList<>();
    private final WebDataBinderFactory dataBinderFactory;
    private final SessionAttributesHandler sessionAttributesHandler;

    public ModelFactory(@Nullable List handlerMethods, WebDataBinderFactory binderFactory, SessionAttributesHandler attributeHandler) {
    
        // 把InvocableHandlerMethod轉(zhuǎn)為內(nèi)部類(lèi)ModelMethod
        if (handlerMethods != null) {
            for (InvocableHandlerMethod handlerMethod : handlerMethods) {
                this.modelMethods.add(new ModelMethod(handlerMethod));
            }
        }
        this.dataBinderFactory = binderFactory;
        this.sessionAttributesHandler = attributeHandler;
    }


    // 該方法完成Model的初始化
    public void initModel(NativeWebRequest request, ModelAndViewContainer container, HandlerMethod handlerMethod) throws Exception {
        // 先拿到sessionAttr里所有的屬性們(首次進(jìn)來(lái)肯定木有,但同一個(gè)session第二次進(jìn)來(lái)就有了)
        Map sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request);
        // 和當(dāng)前請(qǐng)求中 已經(jīng)有的model合并屬性信息
        // 注意:sessionAttributes中只有當(dāng)前model不存在的屬性,它才會(huì)放進(jìn)去
        container.mergeAttributes(sessionAttributes);
        // 此方法重要:調(diào)用模型屬性方法來(lái)填充模型  這里ModelAttribute會(huì)生效
        // 關(guān)于@ModelAttribute的內(nèi)容  我放到了這里:https://blog.csdn.net/f641385712/article/details/98260361
        // 總之:完成這步之后 Model就有值了~~~~
        invokeModelAttributeMethods(request, container);

        // 最后,最后,最后還做了這么一步操作~~~
        // findSessionAttributeArguments的作用:把@ModelAttribute的入?yún)⒁擦腥隨essionAttributes(非常重要) 詳細(xì)見(jiàn)下文
        // 這里一定要掌握:因?yàn)槭褂弥械目涌咏?jīng)常是因?yàn)闆](méi)有理解到這塊邏輯
        for (String name : findSessionAttributeArguments(handlerMethod)) {
        
            // 若ModelAndViewContainer不包含此name的屬性   才會(huì)進(jìn)來(lái)繼續(xù)處理  這一點(diǎn)也要注意
            if (!container.containsAttribute(name)) {

                // 去請(qǐng)求域里檢索為name的屬性,若請(qǐng)求域里沒(méi)有(也就是sessionAttr里沒(méi)有),此處會(huì)拋出異常的~~~~
                Object value = this.sessionAttributesHandler.retrieveAttribute(request, name);
                if (value == null) {
                    throw new HttpSessionRequiredException("Expected session attribute "" + name + """, name);
                }
                // 把從sessionAttr里檢索到的屬性也向容器Model內(nèi)放置一份~
                container.addAttribute(name, value);
            }
        }
    }


    // 把@ModelAttribute標(biāo)注的入?yún)⒁擦腥隨essionAttributes 放進(jìn)sesson里(非常重要)
    // 這個(gè)動(dòng)作是很多開(kāi)發(fā)者都忽略了的
    private List findSessionAttributeArguments(HandlerMethod handlerMethod) {
        List result = new ArrayList<>();
        // 遍歷所有的方法參數(shù)
        for (MethodParameter parameter : handlerMethod.getMethodParameters()) {
            // 只有參數(shù)里標(biāo)注了@ModelAttribute的才會(huì)進(jìn)入繼續(xù)解析~~~
            if (parameter.hasParameterAnnotation(ModelAttribute.class)) {
                // 關(guān)于getNameForParameter拿到modelKey的方法,這個(gè)策略是需要知曉的
                String name = getNameForParameter(parameter);
                Class paramType = parameter.getParameterType();

                // 判斷isHandlerSessionAttribute為true的  才會(huì)把此name合法的添加進(jìn)來(lái)
                // (也就是符合@SessionAttribute標(biāo)注的key或者type的)
                if (this.sessionAttributesHandler.isHandlerSessionAttribute(name, paramType)) {
                    result.add(name);
                }
            }
        }
        return result;
    }

    // 靜態(tài)方法:決定了parameter的名字  它是public的,因?yàn)镸odelAttributeMethodProcessor里也有使用
    // 請(qǐng)注意:這里不是MethodParameter.getParameterName()獲取到的形參名字,而是有自己的一套規(guī)則的

    // @ModelAttribute指定了value值就以它為準(zhǔn),否則就是類(lèi)名的首字母小寫(xiě)(當(dāng)然不同類(lèi)型不一樣,下面有給范例)
    public static String getNameForParameter(MethodParameter parameter) {
        ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
        String name = (ann != null ? ann.value() : null);
        return (StringUtils.hasText(name) ? name : Conventions.getVariableNameForParameter(parameter));
    }

    // 關(guān)于方法這塊的處理邏輯,和上差不多,主要是返回類(lèi)型和實(shí)際類(lèi)型的區(qū)分
    // 比如List它對(duì)應(yīng)的名是:stringList。即使你的返回類(lèi)型是Object~~~
    public static String getNameForReturnValue(@Nullable Object returnValue, MethodParameter returnType) {
        ModelAttribute ann = returnType.getMethodAnnotation(ModelAttribute.class);
        if (ann != null && StringUtils.hasText(ann.value())) {
            return ann.value();
        } else {
            Method method = returnType.getMethod();
            Assert.state(method != null, "No handler method");
            Class containingClass = returnType.getContainingClass();
            Class resolvedType = GenericTypeResolver.resolveReturnType(method, containingClass);
            return Conventions.getVariableNameForReturnType(method, resolvedType, returnValue);
        }
    }

    // 將列為@SessionAttributes的模型數(shù)據(jù),提升到sessionAttr里
    public void updateModel(NativeWebRequest request, ModelAndViewContainer container) throws Exception {
        ModelMap defaultModel = container.getDefaultModel();
        if (container.getSessionStatus().isComplete()){
            this.sessionAttributesHandler.cleanupAttributes(request);
        } else { // 存儲(chǔ)到sessionAttr里
            this.sessionAttributesHandler.storeAttributes(request, defaultModel);
        }

        // 若該request還沒(méi)有被處理  并且 Model就是默認(rèn)defaultModel
        if (!container.isRequestHandled() && container.getModel() == defaultModel) {
            updateBindingResult(request, defaultModel);
        }
    }

    // 將bindingResult屬性添加到需要該屬性的模型中。
    // isBindingCandidate:給定屬性在Model模型中是否需要bindingResult。
    private void updateBindingResult(NativeWebRequest request, ModelMap model) throws Exception {
        List keyNames = new ArrayList<>(model.keySet());
        for (String name : keyNames) {
            Object value = model.get(name);
            if (value != null && isBindingCandidate(name, value)) {
                String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name;
                if (!model.containsAttribute(bindingResultKey)) {
                    WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name);
                    model.put(bindingResultKey, dataBinder.getBindingResult());
                }
            }
        }
    }

    // 看看這個(gè)靜態(tài)內(nèi)部類(lèi)ModelMethod
    private static class ModelMethod {
        // 持有可調(diào)用的InvocableHandlerMethod 這個(gè)方法
        private final InvocableHandlerMethod handlerMethod;
        // 這字段是搜集該方法標(biāo)注了@ModelAttribute注解的入?yún)?        private final Set dependencies = new HashSet<>();

        public ModelMethod(InvocableHandlerMethod handlerMethod) {
            this.handlerMethod = handlerMethod;
            // 把方法入?yún)⒅兴袠?biāo)注了@ModelAttribute了的Name都搜集進(jìn)來(lái)
            for (MethodParameter parameter : handlerMethod.getMethodParameters()) {
                if (parameter.hasParameterAnnotation(ModelAttribute.class)) {
                    this.dependencies.add(getNameForParameter(parameter));
                }
            }
        }
        ...
    }
}

ModelFactory協(xié)助在控制器方法調(diào)用之前初始化Model模型,并在調(diào)用之后對(duì)其進(jìn)行更新。

初始化時(shí),通過(guò)調(diào)用方法上標(biāo)注有@ModelAttribute的方法,使用臨時(shí)存儲(chǔ)在會(huì)話(huà)中的屬性填充模型。

在更新時(shí),模型屬性與會(huì)話(huà)同步,如果缺少,還將添加BindingResult屬性。

關(guān)于默認(rèn)名稱(chēng)規(guī)則的核心在Conventions.getVariableNameForParameter(parameter)這個(gè)方法里,我在上文給了一個(gè)范例,介紹常見(jiàn)的各個(gè)類(lèi)型的輸出值,大家記憶一下便可。參考:從原理層面掌握HandlerMethod、InvocableHandlerMethod、ServletInvocableHandlerMethod的使用【一起學(xué)Spring MVC】

將一個(gè)參數(shù)設(shè)置到@SessionAttribute中需要同時(shí)滿(mǎn)足兩個(gè)條件:

@SessionAttribute注解中設(shè)置了參數(shù)的名字或者類(lèi)型

在處理器(Controller)中將參數(shù)設(shè)置到了Model中(這樣方法結(jié)束后會(huì)自動(dòng)的同步到SessionAttr里)

總結(jié)

這篇文章介紹了@SessionAttribute的核心處理原理,以及也給了一個(gè)Demo來(lái)介紹它的基本使用,不出意外閱讀下來(lái)你對(duì)它應(yīng)該是有很好的收獲的,希望能幫助到你簡(jiǎn)化開(kāi)發(fā)~

相關(guān)閱讀

從原理層面掌握HandlerMethod、InvocableHandlerMethod、ServletInvocableHandlerMethod的使用【一起學(xué)Spring MVC】

知識(shí)交流

==The last:如果覺(jué)得本文對(duì)你有幫助,不妨點(diǎn)個(gè)贊唄。當(dāng)然分享到你的朋友圈讓更多小伙伴看到也是被作者本人許可的~==

**若對(duì)技術(shù)內(nèi)容感興趣可以加入wx群交流:Java高工、架構(gòu)師3群。
若群二維碼失效,請(qǐng)加wx號(hào):fsx641385712(或者掃描下方wx二維碼)。并且備注:"java入群" 字樣,會(huì)手動(dòng)邀請(qǐng)入群**

若文章格式混亂或者圖片裂開(kāi),請(qǐng)點(diǎn)擊`:原文鏈接-原文鏈接-原文鏈接

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/75808.html

相關(guān)文章

  • 原理層面掌握@RequestAttribute、@SessionAttribute使用一起學(xué)S

    摘要:同時(shí)另外一個(gè)目的是希望完全屏蔽掉源生,增加它的擴(kuò)展性。本文我以為例進(jìn)行講解,因?yàn)橐彩呛笸瞥龅淖⒔獠还軓氖褂煤驮砩隙际且荒R粯拥摹W饔脧闹腥?duì)應(yīng)的屬性值。 每篇一句 改我們就改得:取其精華,去其糟粕。否則木有意義 前言 如果說(shuō)知道@SessionAttributes這個(gè)注解的人已經(jīng)很少了,那么不需要統(tǒng)計(jì)我就可以確定的說(shuō):知道@RequestAttribute注解的更是少之又少。我覺(jué)得主...

    why_rookie 評(píng)論0 收藏0
  • 原理層面掌握@ModelAttribute使用使用篇)【一起學(xué)Spring MVC

    摘要:和一起使用參照博文從原理層面掌握的使用一起學(xué)。至于具體原因,可以移步這里輔助理解從原理層面掌握的使用核心原理篇一起學(xué)再看下面的變種例子重要訪問(wèn)。 每篇一句 每個(gè)人都應(yīng)該想清楚這個(gè)問(wèn)題:你是祖師爺賞飯吃的,還是靠老天爺賞飯吃的 前言 上篇文章 描繪了@ModelAttribute的核心原理,這篇聚焦在場(chǎng)景使用上,演示@ModelAttribute在不同場(chǎng)景下的使用,以及注意事項(xiàng)(當(dāng)然有些...

    BenCHou 評(píng)論0 收藏0
  • 原理層面掌握@ModelAttribute使用(核心原理篇)【一起學(xué)Spring MVC

    摘要:雖然它不是必須,但是它是個(gè)很好的輔助官方解釋首先看看官方的對(duì)它怎么說(shuō)它將方法參數(shù)方法返回值綁定到的里面。解析注解標(biāo)注的方法參數(shù),并處理標(biāo)注的方法返回值。 每篇一句 我們應(yīng)該做一個(gè):胸中有藍(lán)圖,腳底有計(jì)劃的人 前言 Spring MVC提供的基于注釋的編程模型,極大的簡(jiǎn)化了web應(yīng)用的開(kāi)發(fā),我們都是受益者。比如我們?cè)贎RestController標(biāo)注的Controller控制器組件上用@...

    wdzgege 評(píng)論0 收藏0
  • 原理層面掌握HandlerMethod、InvocableHandlerMethod使用一起學(xué)

    摘要:并且,并且如果或者不為空不為且不為,將中斷處理直接返回不再渲染頁(yè)面對(duì)返回值的處理對(duì)返回值的處理是使用完成的對(duì)異步處理結(jié)果的處理使用示例文首說(shuō)了,作為一個(gè)非公開(kāi),如果你要直接使用起來(lái),還是稍微要費(fèi)點(diǎn)勁的。 每篇一句 想當(dāng)火影的人沒(méi)有近道可尋,當(dāng)上火影的人同樣無(wú)路可退 前言 HandlerMethod它作為Spring MVC的非公開(kāi)API,可能絕大多數(shù)小伙伴都對(duì)它比較陌生,但我相信你對(duì)它...

    wawor4827 評(píng)論0 收藏0
  • 原理層面掌握HandlerMethod、InvocableHandlerMethod使用一起學(xué)

    摘要:并且,并且如果或者不為空不為且不為,將中斷處理直接返回不再渲染頁(yè)面對(duì)返回值的處理對(duì)返回值的處理是使用完成的對(duì)異步處理結(jié)果的處理使用示例文首說(shuō)了,作為一個(gè)非公開(kāi),如果你要直接使用起來(lái),還是稍微要費(fèi)點(diǎn)勁的。 每篇一句 想當(dāng)火影的人沒(méi)有近道可尋,當(dāng)上火影的人同樣無(wú)路可退 前言 HandlerMethod它作為Spring MVC的非公開(kāi)API,可能絕大多數(shù)小伙伴都對(duì)它比較陌生,但我相信你對(duì)它...

    miya 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

ARGUS

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<