当前位置:网站首页>Application of decorator mode, packaging ServletRequest and adding addparameter method

Application of decorator mode, packaging ServletRequest and adding addparameter method

2022-06-29 09:51:00 milugloomy

What is the decorator mode

Decorator mode (Decorator Pattern) Allow a to Add new functions to existing objects , Without changing its structure , It is a wrapper for existing classes . This pattern creates a Decoration , Used to wrap the original class , And under the premise of maintaining the integrity of class method signature , Provides additional functionality .

key word : Existing objects , Add new features .

The method of subclassing is to add new functions to the parent class , For class . The decorator pattern is for an existing object , Rather than class .

explain

See the following example :

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletRequestWrapper servletRequest = (HttpServletRequestWrapper) req;
    AuthServletRequest request = new AuthServletRequest(servletRequest);
    //...

    chain.doFilter(request, req);
}

there servletRequest Is an existing object , Here we want to dynamically extend servletRequest Methods , The method of subclass inheritance is not easy to implement , But it can be easily realized through decorator mode .

AuthServletRequest It's decoration , Packed the original servletRequest, Guarantee servletRequest Complete case , Implemented additional functions .

Increase method

The gateway is used in the project , The gateway resolves jwt after , take userId and role adopt header Transfer to business item , Structure diagram is as follows :

Business items are obtained userId and role after , I hope it can be stuffed into HttpRequest Of parameter, In this way spring Project Controller Can be directly defined in the method , Simplify the development of business projects . Like this :

RequestMapping("/sysUser")
public MyResEntity sysUser(Integer userId){
    SysUser sysUser = sysUserService.sysUser(userId);
    return new MyResEntity(sysUser);
}

however HttpServletRequest No parameter is added to parameter This method , It is impossible to realize the above requirements .

Here comes the decorator mode . newly added AuthServletRequest class , as follows :

public class AuthServletRequest extends HttpServletRequestWrapper {
    //  Storage request Data Map
    private Map<String, String[]> params = new HashMap<String, String[]>();

    public AuthServletRequest(HttpServletRequestWrapper request) {
        super(request);
        // Put the existing parameter Pass to params
        this.params.putAll(request.getParameterMap());
    }
    // rewrite getParameter, Represents the parameters from the current class map obtain 
    @Override
    public String getParameter(String name) {
        String[] values = params.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }
    // rewrite getParameterValues, Represents the parameters from the current class map obtain 
    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }
    //  The core approach , Add parameter Methods 
    public void addParameter(String name, Object value) {
        if (value != null) {
            System.out.println(value);
            if (value instanceof String[]) {
                params.put(name, (String[]) value);
            } else if (value instanceof String) {
                params.put(name, new String[]{(String) value});
            } else {
                params.put(name, new String[]{String.valueOf(value)});
            }
        }
    }
}

Then add a new filter AuthFilter, The code is as follows :

public class AuthFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequestWrapper servletRequest = (HttpServletRequestWrapper) req;
        AuthServletRequest request = new AuthServletRequest(servletRequest);
        HttpServletResponse response = (HttpServletResponse) res;
        // header The value in is gateway analysis jwt The resulting value 
        String userId = request.getHeader("userId");
        if (userId != null && request.getParameter("userId") == null) {
            request.addParameter("userId", userId);
        }
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {
    }
}

Conclusion

We use decorator mode , Dynamically give... When the project is running ServletRequest Added addParameter Method , Extends the original object .

Decorator pattern is an alternative pattern of inheritance , Its advantage is that it can dynamically extend the functions of an implementation class . The decorator mode is jdk And various frameworks , for example :

stay Java in ,InputStream,FileInputStream,BufferedInputStream etc. IO Stream operation uses decorator mode .

stay spring Use redis Realization session Shared functions ,spring Also use decorator mode to wrap HttpServletRequest, Decoration is SessionRepositoryRequestWrapper, It rewrites getSession Method , from redis Create and get session object .

原网站

版权声明
本文为[milugloomy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/180/202206290855156451.html