Important notes about spring MVC are in the following Baidu network disk connection. Welcome to learn together
Link: https://pan.baidu.com/s/1E1V37apnF7TiFEnUSn82Tg
Extraction code: ee3z
Here are some easily forgotten points in my learning process to make another record for follow-up review
Step 1: create maven project
Step 2: set the packaging method to war type in pom.xml, and then add dependencies
Step 3: create webapp folder under main directory
Step 4: add the web.xml file on the project structure page, and pay attention to configuring the path
Start writing the web.xml file
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- Can pass init-param Label settings SpringMVC The location and name of the configuration file, via load-on-startup Label settings SpringMVC Front end controller DispatcherServlet The initialization time of is when the server starts--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> <!-- /The matching request can be/login or.html or.js or.css The request path of, but/Cannot match.jsp Request path seek,Therefore, you can avoid accessing jsp Page, the request is rejected DispatcherServlet Processing so that the corresponding page cannot be found /*All requests can be matched. For example, when using a filter, if you need to filter all requests, you need to use/*Writing method of--> </servlet-mapping> <!-- Write a character encoding filter and make the corresponding encoding response UTF-8,SpringMVC The filter for processing code in must be configured before other filters, otherwise it will be invalid --> <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> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- The setting request type can be put,delete --> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Step 5: create request controller
Create the corresponding controller layer, write the controller class and add @ controller annotation
Step 6: create the springMVC.xml configuration file in the resource directory
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.it.mvc" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!--set up/Where to access, view controller view-controller--When the controller method is only used to realize page Jump, that is, only the view name needs to be set, the processor method can be used viewcontroller Label to represent When SpringMVC Set any one in view-controller When, all request mappings in other controllers will fail. At this time, you need to SpringMVC Set on in the core configuration file of mvc Annotation driven labels:<mvc:annotation-driven />--> <mvc:view-controller path="/" view-name="index"></mvc:view-controller> <!--Can support springMVC Some more advanced functions are also unconfigured view-controller All other requests are invalid--> <mvc:annotation-driven></mvc:annotation-driven> <!--take springMVC Requests that cannot be processed are handed over to tomcat--> <mvc:default-servlet-handler></mvc:default-servlet-handler> <!--Things needed for file upload--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean> <!--Configuring Interceptors --> <mvc:interceptors> <!--<bean class="com.it.mvc.interceptor.FirstInterceptor"></bean>--> <ref bean="firstInterceptor"></ref> <ref bean="secondInterceptor"></ref> <!--<mvc:interceptor> <mvc:mapping path="/**"/> <!–Everything in the interceptor matches/**,Not really/*–> <mvc:exclude-mapping path="/"/> <ref bean="firstInterceptor"></ref> </mvc:interceptor>--> </mvc:interceptors> <!--Configure exception handling--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.ArithmeticException">error</prop> </props> </property> <property name="exceptionAttribute" value="exceptionAttribute"></property> </bean> <!-- to configure Thymeleaf view resolver --> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <property name="order" value="1"/> <property name="characterEncoding" value="UTF-8"/> <property name="templateEngine"> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!--Therefore, when we write our own projects, we only need to set the prefix and suffix of the view, and the others do not need to be changed--> <!-- The view prefix configures the path of the file you want to resolve--> <property name="prefix" value="/WEB-INF/templates/"/> <!-- View suffix configures the suffix name of the file you want to resolve--> <property name="suffix" value=".html"/> <property name="templateMode" value="HTML5"/> <property name="characterEncoding" value="UTF-8" /> </bean> </property> </bean> </property> </bean> </beans>
Step 7: add tomcat server
index front page code
<body> <p>159357258456</p> <!--With“/"The path at the beginning is called the absolute path. There are two types Server side parsing"/",Represents the current web Application path, i.e.: http://localhost:8080 / project name/ This can be mapped directly to/webapp The following two paths are resolved by the server web.xml Medium"/" request.getRequestDispatcher().forward(request, response);In request forwarding"/" Browser side parsing"/",Represents the path of the current server, that is: http://localhost:8080/ The following two paths are resolved by the browser .html In the page"/",For example: action,src,href Medium"/" response.sendRedirect();In redirection"/"--> <!--Here through thymeleaf Parse path, first add th:Then add@{In the control layer requestMappering It's the same as the one inside. Go there}--> <a th:href="@{/target}">Access target page</a> </body>
Write a method to process the request in the request controller class
@Controller public class HelloController { // The location of the page is / WEB-INF/templates/index.html @RequestMapping(value = "/") /* *Function - Request mapping annotation, which is used to map the current request to this method. The value in it indicates that when the browser sends / matches this method *Annotation location - @ RequestMapping identifies a class: sets the initial information of the request path of the mapping request, and identifies a method: sets the specific information of the request path of the mapping request *Attribute - there are two important attributes in the attribute. One value is an array. You can {'', ''} assign multiple values to the array as long as you match one. There are generally two methods, post and get, which are also an array. If you don't write, they will match by default. If you write, they will match. RequestMethod.POST *@RequestMapping Derived annotation of - --- mapping for processing get requests -- > @ getmapping. Mapping for processing post requests - > @ postmapping. Mapping for processing put requests -- > @ putmapping. Mapping for processing delete requests -- > @ deletemapping */ public String index(){ // Return the view name, because we can't directly access the page, we need to locate the page through the view parsed by the dispatcher servlet // The method located here is not reflection, so it has nothing to do with the method name. It is located through the view name // Note that because we have configured thmleaf, the prefix and suffix have been located in it, so we can give whatever we need return "index"; } /* SpringMVC ant style path supported ?: Represents any single character *: Represents any 0 or more characters **: Represents any one or more levels of directories // Note: when using * *, you can only use / * * / / / xxx*/ @RequestMapping("/**/testA*") @RequestMapping(value = "/target") public String toTarget(){ return "target"; } /* SpringMVC Support placeholders in paths (emphasis) Original method: / deleteuser? Id = 1 rest method: / deleteUser/1 SpringMVC Placeholders in the path are often used in RESTful style. When some data in the request path is transmitted to the server through the path, the transmitted data can be represented by the placeholder {xxx} in the value attribute of the corresponding @ RequestMapping annotation. The data represented by the placeholder is assigned to the formal parameters of the controller method through the @ PathVariable annotation The front end places the parameter < a th: href = "@ {/ testrest / 1 / Admin}" > placeholder in the test path -- > / testrest < / a > < br >*/ @RequestMapping(value = "/testPath/{id}/{username}") // Here 1 is a parameter, but it is written in the address. How to obtain this parameter? The method is to add a placeholder at the position occupied by the parameter, as shown above public String testPath(@PathVariable("id") Integer id, @PathVariable("username") String username){ // The above formal parameter is to resolve the parameters represented by the placeholder in the address System.out.println(id + username); return "sucess"; } }
Spring MVC obtains request parameters in five ways
1. The above placeholder is a way. Passing one is OK. If there are more placeholders, it will be very inconvenient and unsafe
2. It is inconvenient to encapsulate the request domain through the native API. request.getparam
3. Obtain the request parameters through the formal parameters of the controller method
At the formal parameter position of the controller method, set the formal parameter with the same name as the request parameter. When the browser sends a request and matches the request mapping, the
The dispatcher servlet assigns the request parameters to the corresponding formal parameters
html code
<!-- The parameter is of string type, enclosed in single quotes --> <a th:href="@{/testParam(username='admin',password=123456)}">Test get request parameters-->/testParam</a><br>
java code
>@RequestMapping("/testParam") public String testParam(String username, String password){ System.out.println("username:"+username+",password:"+password); return "success"; }
4. Annotation @ RequestParam
When the parameter names are different, the annotation @ RequestParam is used
@RequestParam is to create a mapping relationship between the request parameters and the formal parameters of the controller method
@The RequestParam annotation has three attributes:
value: Specifies the parameter name of the request parameter assigned to the formal parameter, that is, the id in the front end
required: sets whether this request parameter must be transmitted. The default value is true
defaultValue: whether the required property value is true or false, when the request parameter specified by value has no transmitted or transmitted value
When is, the default value is used to assign values to the formal parameters
@RequestParam(value = "user_name", defaultValue = "1", required = false) String username
5. Get request parameters through javabean
You can set an entity class type parameter at the parameter position of the controller method. At this time, if the parameter name and real name of the request parameter transmitted by the browser
If the attribute names in the body class are consistent, the request parameters will assign values to this attribute
Front end code
<form th:action="@{/testpojo}" method="post"> user name:<input type="text" name="username"><br> password:<input type="password" name="password"><br> Gender:<input type="radio" name="sex" value="male">male <input type="radio" name="sex" value="female">female<br> Age:<input type="text" name="age"><br> Email:<input type="text" name="email"><br> <input type="submit"> </form>
java code
First create the corresponding java bean, and then write the code
@RequestMapping("/testpojo") public String testPojo(User user){ System.out.println(user.toString()); return "sucess"; }
Domain objects share data in 7 ways
1. Use the servlet API to share data with the request domain object, request.setAttribute
2. Use ModelAndView to share data with the request domain object
@RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ /** * ModelAndView It has the functions of Model and View * Model It is mainly used to share data with the requesting domain * View It is mainly used to set the view and realize page Jump */ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("testRequestScope", "Hello, ModelAndView"); modelAndView.setViewName("success"); return modelAndView; }
3. Use the Model to share data with the request domain object
@RequestMapping("/testModel") public String testModel(Model model){ model.addAttribute("testRequestScope","Hello, Model"); return "success"; }
4. Use map to share data with the request domain object
@RequestMapping("/testMap") public String testMap(Map<String, Object> map){ map.put("testRequestScope", "Hello, Map"); return "success"; }
5. Use ModelMap to share data with request domain objects
@RequestMapping("/testModelMap") public String testModelMap(ModelMap modelMap){ modelMap.addAttribute("testRequestScope", "Hello, ModelMap"); return "success"; }
6. Share data to the session domain
@RequestMapping("/testSession") public String testSession(HttpSession httpSession){ httpSession.setAttribute("testSessionScope", "Hello, Session"); return "success"; }
7. Share data with the application domain
@RequestMapping("/testApplication") public String testApplication(HttpSession httpSession){ ServletContext application = httpSession.getServletContext(); application.setAttribute("testApplicationScope", "Hello, Application"); return "success"; }
View of spring MVC
There are many kinds of spring MVC views, including forwarding view and redirection view by default
When the project introduces jstl dependency, the forwarding view will be automatically converted to JstlView
If the view technology used is Thymeleaf, the view parser of Thymeleaf is configured in the configuration file of spring MVC. After the view parser parses, the ThymeleafView is obtained
1. ThymeleafView view
Before we wrote the ThymeleafView view, we only need to write the name, prefix and suffix of the view, which are configured in the configuration file
2. Forwarding view
Creating a forwarding view in spring MVC: when the view name is prefixed with "forward:", the InternalResourceView view is created. At this time, the view name will not be resolved by the view parser, but the prefix "forward:" will be removed, and the rest will be used as the final path to jump through forwarding
3. Redirect view
The default redirection view in spring MVC is RedirectView. When the view name is prefixed with "redirect:", the RedirectView view is created. At this time, the view name will not be parsed by the view parser, but the prefix "redirect:" will be removed, and the rest will be used as the final path to jump through redirection
@RequestMapping("/testThymeleafView") public String testThymeleafView(){ return "success"; } // If there is no prefix, it is ThymeleafView, but if there are some, it is not. There are only two kinds of forward and redirect // For example, when forwarding to the above request, use forward: / as shown below, which is not ThymeleafView @RequestMapping("/testForward") public String testForward(){ return "forward:/testThymeleafView"; } // Request forwarding is a browser request, two server requests, and the second request can access internal resources // Request redirection is a two-time browser request that cannot access internal resources, so it can only be forwarded to the request, and then to the internal resources @RequestMapping("/testRedirect") public String testRedirect(){ return "redirect:/testThymeleafView"; }
RESTful
Specifically, in the HTTP protocol, there are four verbs representing the operation mode: GET, POST, PUT and DELETE.
They correspond to four basic operations: GET is used to obtain resources, POST is used to create new resources, PUT is used to update resources, and DELETE
Used to delete resources.
HiddenHttpMethodFilter helps us convert POST requests to DELETE or PUT requests
HiddenHttpMethodFilter conditions for processing put and delete requests:
a> The request mode of the current request must be post
b> The current request must transmit the request parameters_ method
The specific methods are as follows:
First, specify the method type as post type in the front page, and add a hidden label transfer_ Method, as shown below
<form th:action="@{/user}" method="post"> <input type="hidden" name="_method" value="put"> user name:<input type="text" name="username"><br> password:<input type="password" name="password"><br> <input type="submit" value="add to"> </form>
This is written in the controller
@RequestMapping(value = "/user", method = RequestMethod.PUT)
Note that multiple requests of this controller can be / user. As long as the requested methods are different, they will be mapped to different controller methods
The front address bar is spliced with single quotation marks, which passes parameters through placeholders
<a th:href="@{'/employee/' + ${employee.id}}">update</a>
HttpMessageConverter
HttpMessageConverter, message information converter, converts request message into Java object or Java object into response message
writing
HttpMessageConverter provides two annotations and two types: @ RequestBody, @ ResponseBody, @ RequestEntity, ResponseEntity
1,@RequestBody
@RequestBody can obtain the request body. You need to set a formal parameter in the controller method and use @ RequestBody for identification. When
The request body of the previous request will assign a value to the formal parameter identified by the current annotation
<form th:action="@{/testRequestBody}" method="post"> user name:<input type="text" name="username"><br> password:<input type="password" name="password"><br> <input type="submit"> </form>
@RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String requestBody){ System.out.println("requestBody:"+requestBody); return "success"; }
Output results:
requestBody:username=admin&password=123456
2,RequestEntity
RequestEntity encapsulates a type of request message. The formal parameter of this type needs to be set in the formal parameter of the controller method
The request message will be assigned to this parameter. You can get the request header information through getHeaders() and the request body information through getBody()
@RequestMapping("/testRequestEntity") public String testRequestEntity(RequestEntity<String> requestEntity){ System.out.println("requestHeader:"+requestEntity.getHeaders()); System.out.println("requestBody:"+requestEntity.getBody()); return "success"; }
3,@ResponseBody
@ResponseBody is used to identify a controller method. The return value of the method can be directly used as the response body of the response message to the controller
browser
@RequestMapping("/testResponseBody") @ResponseBody public String testResponseBody(){ return "success"; }
Result: the browser page displays success
Therefore, we can use this method to bring the data to the original front-end page after processing
For example, how to handle json:
Import the json package and turn on the mvc annotation driver, so that the return value will be automatically converted into hson format and displayed on the front-end page
@RequestMapping("/testResponseUser") @ResponseBody public User testResponseUser(){ return new User(1001,"admin","123456",23,"male"); }
Results displayed in the browser's page:
{"id": 1001, "username": "admin", "password": "123456", "age": 23, "sex": "male"}
How to handle Ajax
File upload and download
1. File download
// Use ResponseEntity to download files @RequestMapping("/testDown") public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException { //Get ServletContext object ServletContext servletContext = session.getServletContext(); //Gets the real path of the file in the server String realPath = servletContext.getRealPath("/static/img/1.jpg"); //Create input stream InputStream is = new FileInputStream(realPath); //Create byte array byte[] bytes = new byte[is.available()]; //Read stream into byte array is.read(bytes); //Create an HttpHeaders object and set the response header information MultiValueMap<String, String> headers = new HttpHeaders(); //Set the method to download and the name of the file to download headers.add("Content-Disposition", "attachment;filename=1.jpg"); //Set response status code HttpStatus statusCode = HttpStatus.OK; //Create ResponseEntity object ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode); //Close input stream is.close(); return responseEntity; }
2. File upload
File upload requires that the form request method must be post, and the attribute enctype = "multipart / form data" is added
<form th:action="@{testUp}" method="post" enctype="multipart/form-data"> head portrait:<input type="file" name="photo"><br> <input type="submit" value="upload"> </form>
Spring MVC encapsulates the uploaded file into a MultipartFile object, through which you can obtain file related information
Upload steps:
a> Add dependency: Commons fileUpload
b> Add configuration in the configuration file of spring MVC:
<!--The file must be parsed by the file parser to convert the file to MultipartFile object--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> </bean>
c> Controller method:
@PostMapping("/testUp") public String testUp(MultipartFile photo, HttpSession session) throws IOException { // Get the uploaded file name String filename = photo.getOriginalFilename(); // Gets the suffix of the uploaded file String suffixName = filename.substring(filename.lastIndexOf(".")); // Use UUID as file name String uuid = UUID.randomUUID().toString(); filename = uuid + suffixName; // Gets the path to the photo directory in the server ServletContext servletContext = session.getServletContext(); String photoPath = servletContext.getRealPath("photo"); File file = new File(photoPath); // Determine whether the path corresponding to the photoPath exists if(!file.exists()){ // Does not exist, create directory file.mkdir(); } String finalPath = photoPath + File.separator + filename; photo.transferTo(new File(finalPath)); return "success"; }
Interceptor
Browser - > filter - > dispatcher servlet - > interceptor - > controller
1. Interceptor configuration
Interceptors in spring MVC are used to intercept the execution of controller methods
Interceptors in spring MVC need to implement HandlerInterceptor
The interceptor of spring MVC must be configured in the configuration file of spring MVC:
<!--Configuring Interceptors --> <mvc:interceptors> <!-- <bean class="com.it.mvc.interceptor.FirstInterceptor"></bean> <ref bean="firstInterceptor"></ref> --> <!-- The above two configurations are correct DispatcherServlet All requests processed are intercepted --> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/"/> <ref bean="firstInterceptor"></ref> </mvc:interceptor> <!-- The above configuration methods can be ref or bean Tag set interceptor, through mvc:mapping Set the request to be intercepted through mvc:exclude-mapping Set the requests that need to be excluded, that is, the requests that do not need to be intercepted --> </mvc:interceptors>
2. Three abstract methods of interceptor
Interceptors in spring MVC have three abstract methods:
preHandle: the controller method executes preHandle() before execution, and its boolean return value indicates whether to intercept or release, and returns
Return true to release, that is, call the controller method; Returning false indicates interception, that is, the controller method is not called
postHandle: execute postHandle() after the controller method is executed
After compilation: after processing the view and model data, execute after compilation () after rendering the view
@Component public class FirstInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("FirstInterceptor->preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("FirstInterceptor->postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("FirstInterceptor->afterCompletion"); } }
3. Execution sequence of multiple interceptors
a> If each interceptor's preHandle() returns true
At this time, the execution order of multiple interceptors is related to the configuration order of interceptors in the spring MVC configuration file:
preHandle() will execute in the order configured, while postHandle() and aftercompilation () will execute in the reverse order configured
b> If the preHandle() of an interceptor returns false, both the preHandle() returning false and the preHandle() of the interceptor before it will be executed, and the postHandle() will not be executed. The aftercompilation () of the interceptor before the interceptor returning false will be executed
Exception handler
1. Configuration based exception handling
Spring MVC provides an interface to handle exceptions during the execution of controller methods: HandlerExceptionResolver
The implementation classes of HandlerExceptionResolver interface include DefaultHandlerExceptionResolver and
SimpleMappingExceptionResolver
Spring MVC provides a custom exception handler, SimpleMappingExceptionResolver, which can be used as follows:
<!--Configure exception handling--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <!--properties The key of represents an exception that occurs during the execution of the processor method properties The value of indicates that if a specified exception occurs, set a new view name and jump to the specified page--> <props> <prop key="java.lang.ArithmeticException">error</prop> </props> </property> <!--exceptionAttribute Property to set a property name and share the exception information in the request domain--> <property name="exceptionAttribute" value="exceptionAttribute"></property> </bean>
2. Annotation based exception handling
@ControllerAdvice // Represents the current class as a component that handles exceptions public class ExceptionController { // value is an array of class es @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class}) public String testException(Exception exception, Model model){ model.addAttribute("exceptionAttribute", exception); return "error"; } }