preface
As we all know, Java development is nicknamed Spring development by the old subroutine geeks, which shows the status of Spring in Java development. Without the Spring framework, most people write shit.
Spring MVC is one of the most important of Spring’s seven modules.
The MVC framework is a full-featured MVC implementation for building Web applications that is made highly configurable through policy interfaces
Friends who are interested in the other six modules of the Spring framework can directly click on the complete Spring study notes I organized, which has a large number of source code analysis and project practice, you can communicate with them.
Overview of MVC Design
In the early development of Java Web, the unified display layer, control layer, data layer operations are all handed over to JSP or JavaBean for processing, we call Model1:
- Disadvantages:
- There is heavy coupling between JSPS and Java beans, and Java code and HTML code are also coupled together
- Developers are required not only to master Java, but also to have advanced front-end skills
- The front end and the back end depend on each other. The front end needs to wait for the back end to complete, and the back end also depends on the front end to complete in order to conduct effective testing
- Code is hard to reuse
Because of these drawbacks, this approach was soon replaced by servlets + JSP + Java beans. The early MVC model ** (Model2) ** looks like this:
First, the user’s request will arrive at the Servlet, and then invoke the corresponding Java Bean according to the request, and hand all the display results to the JSP to complete. This pattern is called MVC pattern.
- M is for Model. What is a Model? The model is the data, the DAO, the bean
- V is for View and what is a View? It’s a web page, a JSP, that displays the data in the model
- C is for controller. What is a controller? The role of the controller is to display different data models on different views, and servlets play this role.
The Architecture of Spring MVC
In order to solve the persistent layer has not handled the database transaction programming, and to cater to the strong rise of NoSQL, Spring MVC provides a solution:
** The traditional model layer is split into a Business layer (Service) and a Data Access Object (DAO). ** The data access layer is operated under Service through Spring’s declarative transactions, while the business layer also allows us to access NoSQL, which can meet the burgeoning use of NoSQL, which can greatly improve the performance of Internet systems.
- Features: Loose structure, almost all views can be loosely coupled in Spring MVC, module separation and seamless integration with Spring
Hello Spring MVC
Let’s write our first Spring MVC application:
Step 1: Create a New Spring MVC project in IDEA
Call it HelloSpringMVC and click Finish:
IDEA will automatically download the necessary JAR packages for us and create some default directories and files for us. After creation, the project structure is as follows:
Step 2: Modify web.xml
Let’s open web.xml and modify it as shown below:
Change the
element to/to block all requests and submit them to Spring MVC’s background controller for processing.
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Copy the code
Step 3: Edit dispatcher-servlet.xml
This is the Spring MVC mapping configuration file (xxx-servlet.xml), which we edited 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</ props> </property> </bean> <bean id="helloController" class="controller.HelloController"></bean> </beans>Copy the code
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; }}Copy the code
- There is a problem: javax. Servlet package cannot be found
- Solution: Copy the servlet-api.jar package from the [lib] folder on the local Tomcat server to the project [lib] folder and add dependencies
Spring MVC combines the ModelAndView through the ModelAndView object
ModelAndView mav = new ModelAndView("index.jsp");
mav.addObject("message", "Hello Spring MVC");
Copy the code
In this case, the view is the index.jsp model and the data is the message, and the content is “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; }}Copy the code
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>
Copy the code
The content is simple, showing the content of message with an El expression.
Step 6: Deploy Tomcat and its environment
Find Edit Configurations under the [Run] menu item.
Configuring the Tomcat environment:
Select the local Tomcat server and change the name:
Under the Deployment TAB do the following:
Click OK and let’s click on the triangle in the upper right to get the Tomcat server running.
- Problem: The Tomcat server does not start properly
- Cause: The Tomcat server could not find the related JAR package
- Cut and paste the [lib] folder into the [WEB-INF] folder and re-create the dependency:
Step 7: Restart the server
Restart the server and enter localhost/hello
Click to receiveComplete Spring learning Notes
Trace 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
After the request leaves the browser, the first destination is DispatcherServlet, which is a Servlet. We know 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> <! -- Block all requests --> <url-pattern>/</url-pattern> </ servle-mapping >Copy the code
- The job of the DispatcherServlet is to intercept the request and send it to the Spring MVC controller.
Second stop: HandlerMapping
- ** Question: ** A typical application may have multiple controllers. Which controller should these requests go to?
So the DispatcherServlet queries one or more processor maps to determine the next stop for the request, and the processor map makes its decision based on the URL information carried by the request, such as in the example above, We pass the/Hello address to the helloController by configuring simpleUrlHandlerMapping:
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <! <prop Key ="/hello">helloController</ props> </property> </bean> <bean id="helloController" class="controller.HelloController"></bean>Copy the code
Third stop: controllers
Once the appropriate controller is selected, the DispatcherServlet will send the request to the selected controller, where the request will unload its load (user-submitted requests) and wait for the controller to finish processing the information:
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, Javax.mail. Servlet. HTTP. HttpServletResponse HttpServletResponse) throws the Exception {/ / processing logic... }Copy the code
Fourth stop: Return to DispatcherServlet
When the controller completes its logical processing, it usually generates some information that needs to be returned to the user and displayed on the browser, which is called a Model. It’s not enough to just return the raw information — the information needs to be formatted in a user-friendly way, typically 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) used to render the output. It then sends the request back to the DispatcherServlet 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; }Copy the code
Fifth stop: View resolver
In 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 can’t even determine that the view is a JSP.) Instead, it passes just 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 binds directly to the index.jsp view
Sixth stop: Views
Now that the DispatcherServlet knows which view renders the result, the requested task is basically done.
Its final stop is the implementation of the view, where it delivers model data and the requested task is completed. The view uses the model data to render the result, which is passed to the client through the response object.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<h1>${message}</h1>
Copy the code
Configure Spring MVC with annotations
Now that we have some knowledge of Spring MVC and 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 to 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; }}Copy the code
Remove the implemented interface as well.
- A quick explanation:
@Controller
Annotation: Obviously, this annotation is used to declare the controller, but it doesn’t really have much impact on Spring MVC itself. It is only an aid to implement component scanning and can be used@Component
Annotations instead, but I tried it myself and it didn’t work because the above example didn’t have a JSP view parser configured.@RequestMapping
Note: Obviously, this means path/hello
Is mapped to that method
Step 2: Uncomment the previous XML comment
In the dispatcher-servlet. XML file, comment out the previous configuration and add a component scan sentence:
<? 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>--> <! --< ! – /hello path request to 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>Copy the code
Step 3: Restart the server
When the configuration is complete, restart the server and enter localhost/hello.
@requestMapping annotate details
If @requestMapping is applied to a class, then you add an address to all configured mapping addresses for that class, for example:
@Controller @RequestMapping("/wmyskxz") public class HelloController { @RequestMapping("/hello") public ModelAndView handleRequest(....) throws Exception { .... }}Copy the code
- Access address:
localhost/wmyskxz/hello
Configure the view resolver
Remember our Spring MVC request flow, the view parser is responsible for locating the view, and it accepts a logical view name passed by a 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.
- Problems caused:We can put a [test.jsp] page in the [web] root directory that simulates an important data, we don’t have to do anything, restart the server, type in the web page
localhost/test.jsp
I would be able to access it directly, which would causeThe data reveal that. And we can just type it inlocalhost/index.jsp
Try, according to our program above, this will be a blank page, because it is not retrieved${message}
The parameter is directly accessed, which will beAffecting user experience
The solution
We configured our JSP files in the page folder of the WEB-INF folder, which is the default secure directory in the Java WEB. Is not allowed to be accessed directly * (i.e. you say you can never access it via localhost/WEB-INF/) *
But we need to tell this to the view parser, which we do 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>
Copy the code
A view parser built into Spring MVC is configured here. The parser follows a convention that prefixes and suffixes view names to determine the physical path of view resources in a Web application. ** Let’s actually see the effect:
Step 1: Modify the HelloController
Let’s change 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>--> <! --< ! – /hello path request to 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>Copy the code
Step 3: Clip the index.jsp file
Create a new page folder under web-INF 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:
We pass in the logical view name index with the prefix “/WEB-INF/page/” and the suffix “.jsp “to determine the path of the physical view, so that we can put all the views in the page folder later!
- ** Note: ** this configuration is only for dispatcher-servlet.xml
The controller receives the request data
Receiving parameters with a controller is often the first step in developing Spring MVC business logic. To explore the way Spring MVC passes parameters, let’s create 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"> <input type="text" name="password"><br/> < form> < body> </ HTML >Copy the code
If it’s ugly, let’s put it to the test:
Using the Servlet native API:
It’s easy to know that the form will be submitted to the /param directory, so let’s use the Servlet native API 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;
}
Copy the code
Test success:
Use a matching rule of the same name
We can set the parameter name of the method definition to the same as the parameter name passed to the foreground to get the data (namesake matching rule) :
@RequestMapping("/param") public ModelAndView getParam(String userName, String password) { System.out.println(userName); System.out.println(password); return null; }Copy the code
Test success:
- Problem: This leads to strong coupling with the foreground, which we don’t want
- Solution:use
@requestParam (" Foreground parameter name ")
To infuse:
@RequestParam
Note details:This annotation has three variables:value
,required
,defaultvalue
value
: specifyname
What is the name of the property,value
Properties can be left unwritten by defaultrequired
: Specifies whether this parameter is required. It can be set to true or false.defaultvalue
: Sets the default value
Use model to pass parameters
- 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 */
}
Copy the code
Then the test is still successful:
Chinese garbled characters
- Note: As in the Servlet, this method only works with the POST method (since it is a request being processed directly)
We can do this by configuring the Spring MVC character encoding filter to add to web.xml:
<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>Copy the code
The controller displays data
Now that we know how to accept request data, and can solve the problem of POST garbled characters, how to echo data? To do this, create 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 >Copy the code
This is done using the Servlet native API
Let’s test whether the Servlet native API can do the job:
@RequestMapping("/value") public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse Response) {request.setattribute ("message"," success!" ); return new ModelAndView("test1"); }Copy the code
Enter localhost/value in the address bar of the browser to test it
Use the ModelAndView object provided by Spring MVC
Working with Model objects
In Spring MVC, we usually bind data in this way,
- use
@ModelAttribute
Comments:
@modelAttribute public void model(model model) {model.addattribute ("message", "annotation succeeded "); } @RequestMapping("/value") public String handleRequest() { return "test1"; }Copy the code
When the controller method handleRequest() is called, the model() method is called first to add message to the page parameter, which can be called directly from the view, but this will cause all the controller methods to call the Model () method first. But it’s also convenient because you can add all kinds of data.
Client Redirect
Whether address /hello goes to index.jsp or /test goes to test.jsp, these are server-side jumps. Is the request. GetRequestDispatcher (” address “). The forward (request, response);
So how do we do client jump? Let’s go ahead and write 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;
}
Copy the code
Redirect :/hello we use redirect:/hello to redirect to /hello. Restart the server and type localhost/jump into the address bar. This automatically redirect to /hello:
It can also be used like this:
@RequestMapping("/jump")
public String jump() {
return "redirect: ./hello";
}
Copy the code
File upload
Let’s start by reviewing traditional file uploads and downloads: here
How do you implement file upload and download in Spring MVC
- Note:First entry required
Commons - IO - 1.3.2. The jar
和Commons fileupload - 1.2.1 jar
Two packages
Step 1: Configure the upload resolver
Add a new sentence to dispatcher-servlet.xml:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
Copy the code
Enable the upload function
Step 2: Write the JSP
The file name is upload.jsp, and it will still be created under [page] :
<%@ page contentType="text/html; Charset =UTF-8" language=" Java "%> < HTML > <head> <title> Test file upload </title> </head> <body> <form action="/upload" Method ="post" encType ="multipart/form-data"> <input type="file" name="picture"> <input type=" value=" submit" > </form> </body> </html>Copy the code
Step 3: Write the controller
Create class UploadController 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"); }}Copy the code
Step 4: Test
Enter localhost/test2 in the address bar, select the file, and click Upload. The test succeeds.
This article is mainly for those who do not know about Spring MVC, so there must be a lot of things that have not been written, including other modules of the Spring framework, I will update when I have time, so interested friends can click attention, by the way, click a like it!
Of course, if you can’t wait, you can click on the complete Spring study notes
end