JAVAWEB training and writing MVC framework

Keywords: Java servlet mvc

catalogue

1. What is the MVC framework?

1.1 MVC programming mode

1.2 MVC processing flow  

  2. Write a simple MVC framework

2.1 notes

2.2 processor mapper HandlerMapping

2.3 dispatcher servlet of central controller

2.4 combing MVC process

  3. Source code

1. What is the MVC framework?

MVC begins to exist in desktop applications. M refers to the business model and V refers to the business model user interface C is the controller. The purpose of using MVC is to separate the implementation codes of M and V, so that the same program can use different expressions.

1.1 MVC programming mode

  • V    View is the interface that users see and interact with. For example, a web interface composed of html elements, or a software client interface. One of the benefits of MVC is that it can handle many different views for applications. In fact, there is no real processing in the view. It is just a way to output data and allow users to operate.
  • M    A model is a model that represents business rules. Among the three components of MVC, the model has the most processing tasks. The data returned by the model is neutral, and the model has nothing to do with the data format. Such a model can provide data for multiple views. Because the code applied to the model can be reused by multiple views only once, the repeatability of the code is reduced.
  • C    That is, the controller means that the controller accepts the user's input and calls the model and view to complete the user's requirements. The controller itself does not output anything and do any processing. It just receives the request and decides which model component to call to process the request, and then determines which view to use to display the returned data.

1.2 MVC processing flow  

[flow chart description]

1. The user sends a request to the front-end controller DispatcherServlet.

2. front controller DispatcherServlet calls the processor mapper HandlerMapping after receiving the request.

3. The processor mapper HandlerMapping finds the specific processor according to the requested Url, generates the processor object Handler and the processor interceptor handlerinterceptor (if any) and returns them to the front-end controller DispatcherServlet.

4. The front-end Controller DispatcherServlet calls the processor Controller through the processor adapter HandlerAdapter.

5. Execution processor (Controller, also known as back-end Controller)

6. After the processor Controller executes, it returns ModelAnView.

7. The processor mapper HandlerAdapter returns the result ModelAndView returned by the processor Controller execution to the front-end Controller DispatcherServlet.

8. The front-end controller DispatcherServlet transmits ModelAnView to the view parser ViewResolver.

9. The View resolver returns the specific View after parsing.

10. The front-end controller DispatcherServlet renders the View (that is, fills the model data into the View)

11. The front-end controller DispatcherServlet responds to the user.

[excerpted from the original article of CSDN blogger "bright moon and stars _w": Detailed explanation of mvc framework (resource arrangement) bright moon and stars - CSDN blog _mvcframework]

  2. Write a simple MVC framework

Observe the methods in the following class. The url and the corresponding processor are specified here. How can the user correctly call the corresponding processor in the background after the browser enters the url?

2.1 notes

  First, each method (processor) is associated with the url through annotation (value):

  • @Target(ElementType.METHOD) indicates a method annotation
  • @Retention(RetentionPolicy.RUNTIME) means that the annotation is not only saved to the class file, but still exists after the jvm loads the class file. Generally, if it is necessary to dynamically obtain annotation information at RUNTIME, it can only be used   RUNTIME annotation
  • @Documented means that this annotation should be recorded by the javadoc tool. By default, javadoc does not include annotations. However, if @ documented is specified when declaring annotations, it will be processed by tools such as javadoc, so the annotation type information will also be included in the generated document. It is a tag annotation without members.

ResponseBody:

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
/**
 * The method added by this annotation will be used to process the request
 * Method is returned to the client as text
 */
public @interface ResponseBody {
    String value();
}

 ResponseView:

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
/**
 * The method added by this annotation will be used to process the request
 * Method is redirected directly
 */
public @interface ResponseView {
    String value();
}

  2.2 processor mapper HandlerMapping

The processor mapper class is actually a tool class: create mapping, store mapping, and get processor

(1) The processor mapper will physically establish a mapping between the url and the processor:

private static Map<String,MVCMapping> data = new HashMap<>();

  A HashMap is used to save the mapping relationship between the url of String type and the "processor object". The processor object is encapsulated by a static internal class:

/**
 *Mapping objects, each object encapsulates a method for processing requests
 */
public static class MVCMapping{
    private Object object;
    private Method method;
    private ResponseType type;
}

This is because the class we process requests is configured through the configuration file: application.properties

A class may contain multiple method s for processing requests. The annotated type represents the type returned by the processor

(2) The processor mapper provides an external method: get the processor through the url

public static MVCMapping get(String uri)

(3) The processor can read the processor class in the specified stream, parse it into the processor object MVCMapping in method units, and generate a mapping:

public static void load(InputStream is) throws IOException {
        Properties ppt = new Properties();
        ppt.load(is);
        //Get the classes described in the configuration file
        Collection values = ppt.values();
        for (Object cla : values) {
            String className = (String) cla;
            try {
                //Load class
                Class c = Class.forName(className);
                //create object
                Object object = c.getConstructor().newInstance();
                //Gets all methods of the class
                Method[] methods = c.getMethods();
                for (Method m : methods) {
                    Annotation[] annotations = m.getAnnotations();
                    if(annotations!=null) {
                        for (Annotation a : annotations) {
                            if (a instanceof ResponseBody){
                                //Description This method is used to return a string to the client
                                MVCMapping mapping = new MVCMapping(object,m,ResponseType.TEXT);
                                Object o = data.put(((ResponseBody) a).value(),mapping);
                                if(o!=null){//Duplicate request address exists
                                    throw new RuntimeException("Duplicate request address:"+((ResponseBody) a).value());
                                }
                            }else if(a instanceof ResponseView){
                                //Description This method is used to return the interface to the client
                                MVCMapping mapping = new MVCMapping(object,m,ResponseType.VIEW);
                                Object o = data.put(((ResponseView) a).value(),mapping);
                                if(o!=null){//Duplicate request address exists
                                    throw new RuntimeException("Duplicate request address:"+((ResponseBody) a).value());
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

The ResponseType in the above code is a custom enumeration type: it represents the type of response

public enum ResponseType {
    TEXT,VIEW;
}

2.3 dispatcher servlet of central controller

(1) The CPU inherits HttpServlet, which we configure in web.xml:

  • Configuration initialization file
  • Configure to process all url requests
<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>pers.xls.mvc.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contentConfigLocation</param-name>
        <param-value>application.properties</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

(2) Obtain the initialization file by rewriting the init method of the Servlet:

Here, the processor mapping class is called to read the initialization file and establish the mapping

 @Override
    public void init(ServletConfig config) throws ServletException {
        String path = config.getInitParameter("contentConfigLocation");
        InputStream is = DispatcherServlet.class.getClassLoader().getResourceAsStream(path);
        try {
            HandlerMapping.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

(3) By rewriting the Service method, obtain the corresponding processor according to the received request and call the method:

 @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. Get the uri requested by the user
        String uri = req.getRequestURI();
        HandlerMapping.MVCMapping mapping = HandlerMapping.get(uri);
        if (mapping==null){
            resp.sendError(404,"custom MVC:Mapping address does not exist:"+uri);
            return;
        }
        Object obj = mapping.getObject();
        Method method = mapping.getMethod();
        Object result = null;
        try {
            result = method.invoke(obj,req,resp);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        switch (mapping.getType()){
            case TEXT:
                resp.getWriter().println((String) result);
                break;
            case VIEW:
                resp.sendRedirect((String) result);
                break;
        }
    }

2.4 combing MVC process

Now let's sort out the simple MVC processing flow:

  • Through the browser, we enter a specific   url   For example: localhost:8080/login.do

  • The central controller   DispatcherServlet   If the request is accessed for the first time, it will call the init method, load the application.properties configuration file in the src folder, and pass the file input stream to the processor mapper class   HandlerMapping for loading

  • Processor mapper class HandlerMapping loads the file input stream, reads the processor class in the configuration file, analyzes the methods with specific annotations in the class, establishes the mapping from url to "processor object MVCMapping", and stores it in the hash table

  • The central controller   DispatcherServlet   Continue to call the service method and call the processor mapper class HandlerMapping   The get method of gets the "processor object" corresponding to the request uri. If it cannot be obtained, it indicates that there is no mapping from the access address to the processor, and the accessed content does not exist. Extract relevant processing class objects, methods and response types from the obtained "processor objects", and call the method by using Java's reflection mechanism:

          Get the response value, and finally respond to the foreground according to different response types:

  3. Source code

Link: https://pan.baidu.com/s/1kfZAc-Z6DmK0cp1pcEfX7Q 
Extraction code: g8zx

Posted by zubinkasad on Wed, 06 Oct 2021 17:13:00 -0700