In principle level to master the use of @ RequestAttribute, @ SessionAttribute the school with Spring MVC []

Each one

We have to change on a whim: its essence, to its dregs. Otherwise meaningful wood

Foreword

If know @SessionAttributesthis comment very few people, you do not need statistics I can say with certainty: Know @RequestAttributenotes even fewer. I think there are two reasons:

  1. @RequestAttributeThis comment is very new, Spring4.3only after there
  2. We can use API calls ( ServletRequest.getAttribute()) to achieve their goals, without comment. And the cost is not too high

Since Spring launched this comment, it must have its advantages. This article will take you a taste of what it's coquettish place.

SpringThese notes offer such as @ModelAttribute, @SessionAttributes, @RequestAttributeis to simplify development, improve reusability. While a further object is to completely shield off the API Primal the Servlet , increase its scalability.

In this paper I have to @RequestAttributeexplain, for example, because @SessionAttribute(after Spring4.3 also introduced notes) Whether from the use and principles are exactly the same. You can be understood as the only difference is ServletRequest.getAttribute()and HttpSession.getAttribute()the difference between
Again here, this case is: org.springframework.web.bind.annotation.SessionAttributerather thanorg.springframework.web.bind.annotation.SessionAttributes

@RequestAttribute

It than those previously described @ModelAttribute, @SessionAttributesand other notes much simpler, it can only be used in the method to the Senate on . Action: take the request from the corresponding attribute value .

Many small partner of getParameter()and getAttribute()related methods silly you could not tell. I suggest you can be clear paramand attributethe difference between ~

// @since 4.3
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestAttribute {
    @AliasFor("name")
    String value() default "";
    @AliasFor("value")
    String name() default "";

    // 默认情况下 这个属性是必须的(没有就报错了)
    boolean required() default true;
}

The next sentence is important : @RequestAttributeonly take charge of the property value from the request which, as you value when put inside, there is a variety of ways that can be achieved:

  1. @ModelAttributeNotes stored
  2. HandlerInterceptorInterceptor stored
  3. Come forward with a request

The following were used in accordance with the three scenarios, using given Demo:

@ModelAttributeNotes stored

Relatively simple, @ModelAttributeusing the method of label originated by the HttpServletRequestdischarge to a value

@RestController
@RequestMapping
public class HelloController {

    // 放置attr属性值
    @ModelAttribute
    public Person personModelAttr(HttpServletRequest request) {
        request.setAttribute("myApplicationName", "fsx-application");
        return new Person("非功能方法", 50);
    }

    @GetMapping("/testRequestAttr")
    public void testRequestAttr(@RequestAttribute("myApplicationName") String myApplicationName, HttpServletRequest request, ModelMap modelMap) {
        System.out.println(myApplicationName); //fsx-application

        // 从request里获取
        System.out.println(request.getAttribute("myApplicationName")); //fsx-application

        // 从model里获取
        System.out.println(modelMap.get("myApplicationName")); // null 获取不到attr属性的
        System.out.println(modelMap.get("person")); // Person(name=非功能方法, age=50)
    }
}

Request /testRequestAttr, the result is printed as follows:

fsx-application
fsx-application
null
Person(name=非功能方法, age=50)

Be sure to note here: @RequestAttribute("myApplicationName")NOTE If omitted, is not binding properties of Oh attr (must be annotated) ~

However, this is possible: @RequestAttribute String myApplicationName(if annotation is not specified, Spring MVCwill then go to confirm the parameter name automatically bound)
but if you wrote this @RequestAttribute String aaa, that the request directly to the 400 error thrown:org.springframework.web.bind.ServletRequestBindingException

HandlerInterceptorInterceptor stored

Simple, direct on the code:

public class SimpleInterceptor implements HandlerInterceptor {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute("myApplicationName", "fsx-application");
        return true;
    }
    ...
}

Test code: slightly.

forwardCome forward with a request

Thus the form:

request.setAttribute("myApplicationName", "fsx-application");
request.getRequestDispatcher("/index").forward(request, response); 

In fact, the property value is placed inside only need to follow a principle: the target method call processor 之前placement can be anywhere (before parameter package), the property value is being able to take.


Principle analysis

According to my habit, even if it is simple, I will take a look at clawed its principles part of the thing.
According to experience it is easy to think it is a resolve HandlerMethodArgumentResolver, it isRequestAttributeMethodArgumentResolver

RequestAttributeMethodArgumentResolver

Obviously, it is also @since 4.3only appeared, the name is also supporting the thing.

public class RequestAttributeMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {

    // 只处理标注了@RequestAttribute注解的入参
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestAttribute.class);
    }

    // 封装此注解的属性到NamedValueInfo 这里关于参数名的处理有这么一个处理
    // info.name.isEmpty()也就说如果自己没有指定,就用形参名parameter.getParameterName()
    @Override
    protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
        RequestAttribute ann = parameter.getParameterAnnotation(RequestAttribute.class);
        Assert.state(ann != null, "No RequestAttribute annotation");
        return new NamedValueInfo(ann.name(), ann.required(), ValueConstants.DEFAULT_NONE);
    }

    // 从request请求域去找属性值
    @Override
    @Nullable
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request){
        return request.getAttribute(name, RequestAttributes.SCOPE_REQUEST);
    }


    // 若值不存在,抛出异常ServletRequestBindingException
    @Override
    protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException {
        throw new ServletRequestBindingException("Missing request attribute '" + name +
                "' of type " +  parameter.getNestedParameterType().getSimpleName());
    }

}

Source dapper, very simple.
In fact, it resolves into the core of the resolution process parameters in terms of its parent AbstractNamedValueMethodArgumentResolverbody, but not the focus of this article, please refer to HandlerMethodArgumentResolversection ~

@RequestAttributeProperty requireddefaults to true, request.getAttributenot obtain parameters will throw an exception ServletRequestBindingException; required is set to false, even if not get to ignore the request from skipping, assigned to null;

to sum up

This article describes the @RequestAttributeuse of Demoanalysis, and it is very simple principle. Compared to all previous articles, this is very easy, hope to provide everyone an idea to use @RequestAttributeto improve your force grid, ha ha (Tips: loaded to force need to be cautious Oh ~)

Note: Because @SessionAttributeof the use of even a gross principle is almost the same, so we do not repeat the space

to sum up

This article describes @SessionAttributesthe core principles of treatment, and also gave a Demoto introduce its basic use, not surprisingly down to read it you should have a good harvest, hoping to help you simplify the development ~

Related Reading

In principle level to master the use HandlerMethod, InvocableHandlerMethod, ServletInvocableHandlerMethod with the [school] Spring MVC
master the use of @SessionAttributes from the principle of level [together] Spring MVC learn
from the master @ModelAttribute principle level of use (the core principles of article) [together] to learn Spring MVC
in principle grasp @ModelAttribute level of use (use articles) [together] to learn Spring MVC

Knowledge Exchange

== The last: If you think this article helpful to you, may wish to point a praise chant. Of course, your circle of friends to share so that more small partners also are seeing 作者本人许可的~==

If interested in technology content can join the group wx exchange: Java高工、架构师3群.
If the group fails two-dimensional code, please add wx number: fsx641385712(or two-dimensional code is scanned beneath wx). And Note: "java入群"the word, will be invited into the group manually

Guess you like

Origin www.cnblogs.com/fangshixiang/p/11324091.html