The JavaEE architecture consists of four layers: application layer, Web layer, business layer, and persistence layer from top to bottom. Struts and SpringMVC are the frameworks of Web layer, Spring is the framework of business layer, Hibernate and MyBatis are the frameworks of persistence layer.

Why use SpringMVC?

The problem with many applications is that there is a tight coupling between the objects that process the business data and the views that display the business data, and often the commands to update the business objects originate from the view itself, making the view highly sensitive to any changes to the business objects. Moreover, there is no flexibility when multiple views depend on the same business object.

SpringMVC is a Lightweight Web framework based on Java that implements the Web MVC design pattern and request-driven type. It uses the idea of MVC architecture pattern to decouple the responsibilities of the Web layer. Request-based refers to the use of a request-response model. The purpose of the framework is to help simplify development, and SpringMVC is to simplify our daily Web development.

MVC Design pattern

The TASK of the MVC design pattern is to decouple the module that contains the business data from the view that displays the module. How did this happen? Introducing a redirection layer between the model and the view solves the problem. This redirection layer is the controller, which will receive the request, perform an update to the model, and then notify the view of the model changes.

SpringMVC is part of Spring, as shown in the following figure:

The core architecture of SpringMVC:

Specific process:

(1) First, the browser sends the request — >DispatcherServlet, and the front-end controller does not process the request itself after receiving it, but delegates it to other parsers for processing, as a unified access point for global process control;

(2) DispatcherServlet — >HandlerMapping, the Handler mapper will map the request to the HandlerExecutionChain object (contains one Handler Handler object, multiple HandlerInterceptor interceptor objects);

(3) DispatcherServlet — >HandlerAdapter, processor adapter will wrap the processor as an adapter, so as to support many types of processors, that is, the application of the adapter design pattern, so as to easily support many types of processors;

(4) HandlerAdapter — > call the corresponding function processing method of the processor, and return a ModelAndView object (including model data, logical view name);

(5) ModelAndView object (Model part is the Model data returned by the business object, View part is the logical View name) — > ViewResolver, View parser will resolve the logical View name into a specific View;

(6) View — > Render, View will render according to the Model data passed in, the Model here is actually a Map data structure;

(7) Control is returned to the DispatcherServlet, which returns the response to the user and the process ends.

SpringMVC starter program

(1) web. XML

<web-app> <servlet> <! <servlet-name> </servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <! File name: servlet-name-servlet. XML ==== springmVC-servlet. XML * Path specification: must change the load path in web-INF directory:  --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>Copy the code

(2) for springmvc. XML

<beans> <! Configure the mapping handler: find the handler based on the URL of the bean's name property. For springmvc default mapping processor is BeanNameUrlHandlerMapping - > < bean class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <! - configuration processor adapter to perform Controlelr, for springmvc default is SimpleControllerHandlerAdapter - > < bean class ="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean> <! -- Configure custom Controller --> <bean id="myController" name="/hello.do" class="org.controller.MyController"></bean> <! -- Configure sprigMVC view parser: parse logic attempt; The index view parser resolves the real physical view: prefix + logical attempt + suffix ====/WEB-INF/ JSPS /index.jsp --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsps/"></property>
		<property name="suffix" value=".jsp"></property>		
	</bean>
</beans>
Copy the code

(3) Custom processor

public class MyController implements Controller{ public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { ModelAndView mv = new ModelAndView(); Mv.addobject ("hello"."Welcome to SpringMVC!"); // Return to physical view //mv.setViewName("/WEB-INF/jsps/index.jsp"); // Return logical view mv.setViewName("index");
		returnmv; }}Copy the code

(4) Index page

<html>
<body>
<h1>${hello}</h1>
</body>
</html>
Copy the code

(5) Test address

http://localhost:8080/springmvc/hello.do
Copy the code

HandlerMapping

The processor mapper will map requests to HandlerExecutionChain objects (containing one Handler Handler object and multiple HandlerInterceptor interceptors). With this policy pattern, it is easy to add new mapping policies.

There are three kinds of processor mapper, three can coexist, does not affect each other, respectively is BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping and ControllerClassNameHandlerMapping;

BeanNameUrlHandlerMapping

The default mapper, even if not configured, uses this by default to map requests.

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> // The mapper maps the hello.do request to the handler <bean id="testController" name="/hello.do" class="org.controller.TestController"></bean>
Copy the code

SimpleUrlHandlerMapping

The processor mapper can configure multiple mappings for one processor.

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="mappings">
		<props>
			<prop key="/ss.do">testController</prop>
			<prop key="/abc.do">testController</prop> </props> </property> </bean> // This mapping configuration above means that multiple *.do files can access the same Controller. <bean id="testController" name="/hello.do" class="org.controller.TestController"></bean>
Copy the code

ControllerClassNameHandlerMapping

The processor mapper can access the corresponding processor through [classname.do] without manually configuring the mapping.

// With this Mapping configuration, we can access the Controller using the [class name.do] of the Controller.

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>
Copy the code

HandlerAdapter

There are two kinds of processor adapter, can co-exist, is SimpleControllerHandlerAdapter and HttpRequestHandlerAdapter respectively.

SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter is the default adapter, all realized the org springframework. Web. Servlet. MVC. The Controller interface processor are through this adapter adapter, execution.

HttpRequestHandlerAdapter the adapter will be encapsulated into HttpServletResquest HTTP requests and the HttpServletResponse object. All realized the org. Springframework. Web. HttpRequestHandler interface processor are through this adapter adapter, execution. Here is an example:

(1) the configuration HttpRequestHandlerAdapter adapter

<! - configuration HttpRequestHandlerAdapter adapter - > < bean class ="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
Copy the code

(2) Write the processor

public class HttpController implements HttpRequestHandler{ public void handleRequest(HttpServletRequest request, HttpServletResponse Response) throws ServletException, IOException {// Set a value for Request and echo request.setAttribute("hello"."This is HttpRequestHandler!"); / / jump page request. GetRequestDispatcher ("/WEB-INF/jsps/index.jsp").forward(request, response); }}Copy the code

(3) Index page

<html>
<body>
<h1>${hello}</h1>
</body>
</html>
Copy the code

Adapter source code analysis

Simulation scenario: The front-end controller (DispatcherServlet) receives the Handler object and passes it to the corresponding processor adapter (HandlerAdapter), which invokes the corresponding Handler method.

(1) Analog processor

Interface Controller{} public class SimpleController implements Controller{public voiddoSimpleHandler() {
		System.out.println("Simple...");
	}
}

public class HttpController implements Controller{
	public void doHttpHandler() {
		System.out.println("Http...");
	}
}

public class AnnotationController implements Controller{
	public void doAnnotationHandler() {
		System.out.println("Annotation.."); }}Copy the code

(2) Analog processor adapter

Public Interface HandlerAdapter {public Boolean supports(Object handler); public void handle(Object handler); } public class SimpleHandlerAdapter implements HandlerAdapter{ public boolean supports(Object handler) {return (handler instanceof SimpleController);
	}

	public void handle(Object handler) {
		((SimpleController)handler).doSimpleHandler();
	}
}

public class HttpHandlerAdapter implements HandlerAdapter{
	public boolean supports(Object handler) {
		return (handler instanceof HttpController);
	}

	public void handle(Object handler) {
		((HttpController)handler).doHttpHandler();
	}
}

public class AnnotationHandlerAdapter implements HandlerAdapter{
	public boolean supports(Object handler) {
		return(handler instanceof AnnotationController); } public void handle(Object handler) { ((AnnotationController)handler).doAnnotationHandler(); }}Copy the code

(3) Simulate DispatcherServlet

public class Dispatcher {
	public static List<HandlerAdapter> handlerAdapter = new ArrayList<HandlerAdapter>();
	
	public Dispatcher(){ handlerAdapter.add(new SimpleHandlerAdapter()); handlerAdapter.add(new HttpHandlerAdapter()); handlerAdapter.add(new AnnotationHandlerAdapter()); } // Core functions public voiddoDispatch() {SimpleController Handler = new SimpleController(); //HttpController handler = new HttpController(); AnnotationController handler = new AnnotationController(); // Pass to the corresponding processor adapter (HandlerAdapter) HandlerAdapter = getHandlerAdapter(handler); // The Handler adapter calls the corresponding Handler method handlerAdapter.handle(Handler); } public HandlerAdapter getHandlerAdapter(Controller Handler) {for(HandlerAdapter adapter : handlerAdapter){
			if(adapter.supports(handler)){
				returnadapter; }}returnnull; }}Copy the code

(4) Test

public class Test { public static void main(String[] args) { Dispatcher dispather = new Dispatcher(); dispather.doDispatch(); }}Copy the code

Handler

There are only two types of processors mentioned above, but there are many other types of processors that are suitable for various application scenarios, especially the Controller interface, and there are many implementation classes for you to learn about.

Controller

Org. Springframework. Web. Servlet. MVC. Controller, the processor is SimpleControllerHandlerAdapter corresponding adapter.

public interface Controller {

	/**
	 * Process the request and return a ModelAndView object which the DispatcherServlet
	 * will render. A {@code null} return value is not an error: it indicates that
	 * this object completed request processing itself and that there is therefore no
	 * ModelAndView to render.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @return a ModelAndView to render, or {@code null} if handled directly
	 * @throws Exception in case of errors
	 */
	ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}
Copy the code

The processor method is used to process the request submitted by the user, and realizes the calculated response to the user request by calling the code of service layer, and finally encapsulates the calculated data and the page to be responded into a ModelAndView object, which is returned to the front-end controller (DispatcherServlet).

Controller interface implementation class:

HttpRequestHandler

Org. Springframework. Web. HttpRequestHandler, the processor is HttpRequestHandlerAdapter corresponding adapter.

public interface HttpRequestHandler {
    void handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException;
}
Copy the code

This processor method has no return value and cannot encapsulate data and target view as an object like ModelAndView, but it can put data into domain attributes such as Request and Session, and complete the jump of target page by Request or Response.

The ViewResolver View parser is responsible for generating the View View from the result of processing. There are two common view parsers:

InternalResourceViewResolver

This view parser is used to encapsulate and redirect resources within the current Web application. The search rule for internal resources is to combine the view name specified in ModelAndView with the prefix and suffix configured by the view parser to form a Web application internal resource path. Internal resource path = prefix + View name + suffix.

InternalResourceViewResolver parser will return the handler method of model attributes are stored to the corresponding request, and then forwards the request to the target URL.

(1) processor

public class MyController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.addObject("hello"."hello world!");
        mv.setViewName("index");
        returnmv; }}Copy the code

(2) View parser configuration

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
   </bean>
Copy the code

Of course, if you do not specify the prefix and suffix, you can write the internal resource path to setViewName() directly, equivalent to the prefix and suffix are empty string.

mv.setViewName("/WEB-INF/jsp/index.jsp");
Copy the code

BeanNameViewResolver

InternalResourceViewResolver view parser is a problem, it is only after completing internal resource encapsulation can jump, can’t jump to external resources, such as external web pages.

The BeanNameViewResolver view parser encapsulates resources (internal and external) as bean instances, and then specifies the resources in ModelAndView by setting the ID value of the bean instance. Multiple resource beans can be configured simultaneously in a configuration file.

(1) processor

public class MyController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

        return new ModelAndView("myInternalView");
//        return new ModelAndView("baidu"); }}Copy the code

(2) View parser configuration

<! -- View parser --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/ > <! <bean id="myInternalView" class="org.springframework.web.servlet.view.JstlView">
    <property name="url" value="/jsp/show.jsp"/> </bean> <! View --> <bean id="baidu" class="org.springframework.web.servlet.view.RedirectView">
    <property name="url" value="https://www.baidu.com/"/>
</bean>
Copy the code

If you’re familiar with both view parsers, yes, request forwarding and redirection.

Chinese garbled solution

The Get request is garbled

Tomcat8 has solved Get request garbled characters. If Tomcat8 versions are later than Tomcat8, you can use the following two methods:

Change the Tomcat configuration file server.xml

  • Re-code the parameters
String userName = new String (request. GetParamter (" userName "). GetBytes (" ISO - 8859-1 "), "utf-8"); //ISO-8859-1 is the default encoding for versions below Tomcat8Copy the code

The Post request is garbled

Add to web.xml:

<filter>
    <filter-name>characterEncoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
Copy the code

Source:Blog.csdn.net/litianxiang…

Related articles

  • Spring foundation for preparation of handwriting Spring framework
  • Handwritten Spring framework preparation for Spring core AOP
  • Spring core transaction management in preparation for the handwritten Spring framework

Open Source Project Recommendation

The authors recommend open source projects:

  • Pre Is a RBAC permission management system based on Spring Boot, Spring Security, and Vue
  • Prex based on Spring Cloud, Oauth2, Vue of the front and back end separation of the microservice architecture RBAC permission management system

Concern public number reply open source project can be obtained