preface
As we all know, Java development is called Spring development by the old master subroutine apes, which shows the status of Spring in Java development. Without the Spring framework, most people’s code would be shit.
Spring MVC is one of the most important of Spring’s seven modules.
The MVC framework is a full-featured implementation of MVC for building Web applications. The MVC framework becomes highly configurable through the policy interface
If you are interested in the other 6 modules of the Spring framework, you can directly click and get the complete Spring learning notes I organized. There are a lot of source code analysis and project practice, you can communicate with me.
MVC Design Overview
In the early development of Java Web, the operations of display layer, control layer and data layer were all handed over to JSP or JavaBeans for processing, which we called Model1:
- Disadvantages:
- There is a strong coupling between JSPs and Java beans, as well as between Java code and HTML code
- Developers are required not only to master Java, but also to have a superb front-end level
- The front end and the back end depend on each other, with the front end waiting for the back end to complete and the back end depending on the front end to complete effective testing
- Code is hard to reuse
Due to these disadvantages, this approach was quickly replaced by Servlets + JSPs + Java Beans. The early MVC model (Model2) looked something like this:
First, the user’s request will arrive at the Servlet, then call the corresponding Java Bean according to the request, and hand over all the display results to the JSP to complete the pattern, which is called the MVC pattern.
- M is for Model, what is a Model? The model is the data, the DAO, the bean
- V is for View, so what’s a View? It’s the Web page, the JSP, that presents the data in the model
- C is for controller. What’s a controller? The role of the controller is to display different models of data in different views. Servlets play this role.
Spring MVC architecture
In order to solve the persistent layer has not been processed database transactions programming, and to cater to the strong rise of NoSQL, Spring MVC provides a solution:
The traditional model layer is split into Service layer (Service) and Data Access layer (DAO). Spring’s declarative transactions can be used to manipulate the data access layer under the Service, and NoSQL can be accessed on the business layer, which can meet the needs of NoSQL, which can greatly improve the performance of Internet systems.
- Features: Loose structure, almost all kinds of views can be loosely coupled in Spring MVC, and each module is separated and seamlessly integrated with Spring
-
- *
Hello Spring MVC
Let’s write our first Spring MVC program:
Step 1: Create a new Spring MVC project in IDEA
And call it HelloSpringMVC, click [Finish] :
IDEA will automatically help us download the necessary JAR packages, and create some default directories and files for us. After the creation of the project structure is as follows:
Step 2: Modify web.xml
Let’s open the web.xml and complete the modification as shown in the following image:
Change the
element to /, indicating that all requests are to be intercepted and handled by the Spring MVC background controller. After this change:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Step 3: Edit dispatcher-servlet.xml
The beginning dispatcher of this filename corresponds to the dispatcher configured by the
element in the web.xml above. This is the mapping configuration file of Spring MVC (XXX -servlet.xml). We edit it as follows:
<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <! > <prop key="/hello"> HelloController </prop> </props> </property> </bean> <bean id="helloController" class="controller.HelloController"></bean> </beans>
Step 4: Write the HelloController
In Package created under the controller 】 【 【 HelloController 】 classes, and realize the org. Springframework. Web. Servlet. MVC. Controller interface:
package controller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class HelloController implements Controller{ @Override public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { return null; }}
- Problem: The javax.servlet package cannot be found
- Solution: Copy the servlet-api.jar package from the directory [lib] of the local Tomcat server to the project [lib] folder and add dependencies
Spring MVC brings the ModelAndView together through the ModelAndView object
ModelAndView mav = new ModelAndView("index.jsp");
mav.addObject("message", "Hello Spring MVC");
So in this case the view is the index.jsp model and the data is a message that says “Hello Spring MVC.”
package controller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; public class HelloController implements Controller { public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { ModelAndView mav = new ModelAndView("index.jsp"); mav.addObject("message", "Hello Spring MVC"); return mav; }}
Step 5: Prepare index.jsp
Change the contents of index.jsp to:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<h1>${message}</h1>
The content is very simple, using an EL expression to display the contents of Message.
Step 6: Deploy Tomcat and its associated environment
Go to “Edit Configurations” under the “Run” menu.
Configure the Tomcat environment:
Select the local Tomcat server and change the name:
Under the Deployment TAB, complete the following:
Click OK and we’ll get the Tomcat server up and running by clicking the triangle in the upper right corner.
- Problem: The Tomcat server failed to start properly
- Cause: The Tomcat server could not find the associated JAR package
- Clip-and-paste the entire [lib] folder to [WEB-INF] and re-create the dependency:
Step 7: Restart the server
Restart the server and enter the address: localhost/hello
Click to receiveComplete Spring Learning Notes
Tracking Spring MVC requests
Each time the user click the link in your Web browser or submit the form, the request to work, like the postman, returning from leave the browser to get a response, it will experience a lot of sites, leaving some of the information on every site will also bring other information, the image below for the request of the Spring MVC process:
First stop: DispatcherServlet
When the request leaves the browser, the first stop is the DispatcherServlet, look at the name and this is a Servlet that we learned from J2EE that servlets can intercept and process HTTP requests, The DispatcherServlet intercepts all requests and sends them to the Spring MVC controller.
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <! > <url-pattern>/</url-pattern> </servlet-mapping> -- intercept all requests --> <url-pattern>/</url-pattern> </servlet-mapping>
- The task of the DispatcherServlet is to intercept requests sent to the Spring MVC controller.
Stop 2: HandlerMapping
- Question: There may be multiple controllers in a typical application. Which controller should these requests be directed to?
So the DispatcherServlet will query one or more processor mappings to determine the next stop of the request, and the processor mappings will make decisions based on the URL information carried by the request, such as in the example above, Let’s assign the /hello address to the HelloController by configuring SimpleLHandlerMapping:
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <! > <prop key="/hello"> HelloController </prop> </props> </property> </bean> <bean id="helloController" class="controller.HelloController"></bean>
Third stop: the controller
Once the appropriate controller has been selected, the DispatcherServlet sends the request to the selected controller, where the request is unloaded (the user-submitted request) and waits for the controller to process the information:
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, Javax.mail. Servlet. HTTP. HttpServletResponse HttpServletResponse) throws the Exception {/ / processing logic... }
Stop 4: Return the DispatcherServlet
When the controller has finished the logical processing, it usually produces some information, which is the information that needs to be returned to the user and displayed in the browser, which is called the Model. It’s not enough to just return the raw information — the information needs to be formatted in a user-friendly way, usually HTML, so the information needs to be sent to a view, usually a JSP.
The last thing the controller does is wrap up the model data and represent the view name (logical view name) that will be used for rendering output. It then sends the request back to the DispatcherServlet, along with the model and view name.
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, Javax.mail. Servlet. HTTP. HttpServletResponse HttpServletResponse) throws the Exception {/ / processing logic... // Return mav to DispatcherServlet; }
Fifth stop: View parser
This way, the controller is not coupled to a particular view, and the view name passed to the DispatcherServlet does not directly represent a particular JSP. (In fact, it’s not even sure that the view is a JSP.) Instead, it just passes a logical name that will be used to find the real view that produced the result.
The DispatcherServlet will use the View Resolver to match the logical view name to a specific view implementation, which may or may not be a JSP
The example above is directly bound to the index.jsp view
Stop 6: View
Now that the DispatcherServlet already knows which view to render the results from, the requested task is basically done.
Its last stop is the implementation of the view, where it delivers the model data and the requested task is done. The view renders the result using the model data, and the output is passed to the client via the response object.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<h1>${message}</h1>
Configure Spring MVC using annotations
Now that we know a little bit about Spring MVC and have created our first Spring MVC application using XML configuration, let’s look at how to configure the application based on annotations:
Step 1: Add annotations for the HelloController
package controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class HelloController{ @RequestMapping("/hello") public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { ModelAndView mav = new ModelAndView("index.jsp"); mav.addObject("message", "Hello Spring MVC"); return mav; }}
The implementation of the interface is also removed.
- A brief explanation:
@Controller
Comments:
Obviously, this annotation is used to declare controllers, but in fact this annotation has little effect on Spring MVC itself. Spring Acts says that it is only to assist the implementation of component scanning, can be used@Component
The above example does not have a JSP view parser configured. I even have one of my own, but it still doesn’t work.@RequestMapping
Comments:
Obviously, this is the path/hello
Will map to the method
Step 2: Uncomment the previous XML
In the dispatcher-servlet.xml file, comment out the previous configuration and add a component scan:
<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <! --<bean id="simpleUrlHandlerMapping"--> <! --class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">--> <! --<property name="mappings">--> <! --<props>--> <! --< ! – The request for the /hello path is handed to the controller with id HelloController – > -- > <! --<prop key="/hello">helloController</prop>--> <! --</props>--> <! --</property>--> <! --</bean>--> <! --<bean id="helloController" class="controller.HelloController"></bean>--> <! > <context:component-scan base-package="controller"/> </beans>
Step 3: Restart the server
When the configuration is complete, restart the server and type localhost/hello address to still see the result:
@RequestMapping annotates details
If @RequestMapping is applied to a class, it is equivalent to appending an address to all configured mapping addresses of the class, for example:
@Controller @RequestMapping("/wmyskxz") public class HelloController { @RequestMapping("/hello") public ModelAndView handleRequest(....) throws Exception { .... }}
- Then access address:
localhost/wmyskxz/hello
-
- *
Configure the view parser
Remember our Spring MVC request flow, the view parser is responsible for locating the view, and it accepts a logical view name passed by the DispaterServlet to match a particular view.
- Requirements: There are some pages that we do not want users to access directly, such as pages with important data, such as pages supported by model data.
- Caused problems:
We can place [test. JSP] in the root directory of [web] to simulate a page of important data, we don’t have to do anything, restart the server, and type in the pagelocalhost/test.jsp
I’ll be able to access it directly, and that will causeThe data reveal that.
Or we can just type it inlocalhost/index.jsp
Try, according to our above procedure, this will be a blank page, because it is not retrieved${message}
Parameter is accessed directly. This willImpact on user experience
The solution
We configured our JSP files in the [PAGE] folder in the [WEB-INF] folder, which is the default secure directory in the Java Web, You will not be able to access it directly (i.e. you say you will never be able to access it via localhost/ web-inf/etc)
But we need to tell this to the view parser, so we do the following configuration in the dispatcher-servlet.xml file:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/" />
<property name="suffix" value=".jsp" />
</bean>
A view parser built into Spring MVC is configured here, which follows the convention of adding prefixes and suffixes to view names to determine the physical path of view resources in a Web application. Let’s actually look at the effect:
Step 1: Modify the HelloController
Let’s modify the code:
Step 2: Configure the view parser:
According to the above configuration, complete:
<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <! --<bean id="simpleUrlHandlerMapping"--> <! --class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">--> <! --<property name="mappings">--> <! --<props>--> <! --< ! – The request for the /hello path is handed to the controller with id HelloController – > -- > <! --<prop key="/hello">helloController</prop>--> <! --</props>--> <! --</property>--> <! --</bean>--> <! --<bean id="helloController" class="controller.HelloController"></bean>--> <! > <context:component-scan base-package="controller"/> <bean id=" ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/page/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
Step 3: Cut and paste the index.jsp file
Create a new [Page] folder under the [WEP-INF] folder and cut and paste the [index.jsp] file into it:
Step 4: Update resources and restart the server
accesslocalhost/hello
Path to see the correct effect:
- Principle:
The logical view we pass in is called index, plus the prefix “/ web-inf /page/” and the suffix “.jsp “to determine the path to the physical view, so that we can later put all the views in the [pages] folder!
- Note: The configuration at this point is only under dispatcher-servlet.xml
-
- *
The controller receives the requested data
Receiving parameters using a controller is often the first step in developing business logic for Spring MVC. To explore how Spring MVC passes parameters, let’s start by creating a simple form for submitting data:
<! DOCTYPE html> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%> <html> <head> <meta charset="utf-8"> </title> </head> <body> <form action="/param" role="form" <input type="text" name="userName"><br/ BBB > <input type="text" name="password"><br/> <input type="submit" value=" >< /form> </body> </ HTML >
To be ugly, here’s the test:
Using the Servlet native API:
We can easily see that the form will be submitted to the /param directory, so let’s use the Servlet native API first to see if we can get the data:
@RequestMapping("/param")
public ModelAndView getParam(HttpServletRequest request,
HttpServletResponse response) {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
System.out.println(userName);
System.out.println(password);
return null;
}
Test successful:
Use the same name matching rule
We can get the data (matching rule with the same name) by setting the parameter name of the method definition to be the same as the parameter name passed in the foreground:
@RequestMapping("/param")
public ModelAndView getParam(String userName,
String password) {
System.out.println(userName);
System.out.println(password);
return null;
}
Test successful:
- Problem: This creates a strong coupling with the front desk, which we don’t want
- Solution:use
@requestParam (" foreground parameter name ")
To infuse: @RequestParam
Notes details:
This annotation has three variables:value
,required
,defaultvalue
value
: specifyname
What’s the name of the property,value
Properties can be left unwritten by defaultrequired
: Whether this parameter is required, can be set to true or false.defaultvalue
: Set default values
Passing parameters using models
- Requirement: The foreground parameter name must be the same as the field name in the model
Let’s start by creating a User model for our form:
package pojo;
public class User {
String userName;
String password;
/* getter and setter */
}
Then the test is still successful:
Chinese garbled code problem
- Note: As in servlets, this method only works with POST methods (because it is a direct request).
We can do this by configuring the Spring MVC character encoding filter by adding:
<filter> <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
The controller echoes the data
So we know how to accept the request data and solve the POST mess problem, so how do we echo the data? To do this we create a [test2.jsp] under [page] :
<! DOCTYPE html> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" isELIgnored="false" %> <html> <head> <title>Spring MVC Echo data < / title > < / head > < body > < h1 > echo data: ${message} < / h1 > < / body > < / HTML >
Use the Servlet native API to implement
Let’s test the Servlet native API to see if it does the job:
@RequestMapping("/value") public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse Response) {request.setAttribute("message"," Success!" ); return new ModelAndView("test1"); }
In the browser address bar, type: localhost/value test
Use the ModelAndView object provided by Spring MVC
Using the Model object
In Spring MVC, we usually bind data in this way,
-
use
@ModelAttribute
Comments:@modelAttribute public void model(model model) {model.addAttribute(" Message ", "Attribute successfully "); } @RequestMapping("/value") public String handleRequest() { return "test1"; }
When you access the controller’s handleRequest() method, it will call the model() method first to add message to the page parameter, which can be called directly from the view, but it will cause all of the controller’s methods to call the model() method first. But it’s also convenient, because you can add all kinds of data.
Client jump
JSP, or /test to test.jsp. These are server-side jumps, Is the request. GetRequestDispatcher (” address “). The forward (request, response);
So how do we do a client-side jump? Let’s go ahead and write it in HelloController:
@RequestMapping("/hello")
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mav = new ModelAndView("index");
mav.addObject("message", "Hello Spring MVC");
return mav;
}
@RequestMapping("/jump")
public ModelAndView jump() {
ModelAndView mav = new ModelAndView("redirect:/hello");
return mav;
}
If we use redirect:/hello to indicate that we want to jump to the /hello path, we restart the server and enter: localhost/jump in the address bar. It will automatically jump to the /hello path:
It can also be used like this:
@RequestMapping("/jump")
public String jump() {
return "redirect: ./hello";
}
File upload
Let’s review traditional file uploads and downloads first: here
Let’s take a look at how to upload and download files in Spring MVC
- Note:Need pilot entry
Commons - IO - 1.3.2. The jar
和Commons fileupload - 1.2.1 jar
Two packages
Step 1: Configure the upload parser
Add a new line to dispatcher-servlet.xml:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
Enable support for uploading
Step 2: Write the JSP
The file is called Upload.jsp and is still created under [page] :
<%@ page contentType="text/html; Charset = utf-8 "language=" Java" %> < HTML > <head> <title> </head> <form action="/upload" Method ="post" encType ="multipart/form-data"> <input type="file" name="picture"> <input type="submit" value=" post" > <input type="file" name="picture </form> </body> </html>
Step 3: Write the controller
Create a new UploadController class under Package [Controller] :
package controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; @Controller public class UploadController { @RequestMapping("/upload") public void upload(@RequestParam("picture") MultipartFile picture) throws Exception { System.out.println(picture.getOriginalFilename()); } @RequestMapping("/test2") public ModelAndView upload() { return new ModelAndView("upload"); }}
Step 4: Test
Enter localhost/test2 in the browser address bar, select file and click upload. The test is successful:
This article is mainly for those who are not familiar with Spring MVC, so there must be a lot of things not written, including other modules of the Spring framework, I will update it when there is time, so interested friends can point to follow, by the way, point to like it!
Of course, if you can’t wait, you can click to get the complete Spring learning notes
end