SpringMVC
The concept of MVC
- Model1 mode
- Model 1: the combination of JSP page and JavaBean does not use the java Servlet form to write the front-end and back-end interactions, almost all of which are in the charge of JSP
- Model2 mode
-
M: The Model model (JavaBean) is responsible for the data logic part, including business logic, access to the database, and save the data status
- Model 2: JSP+Servlet+JavaBean, to achieve a certain degree of decoupling
-
5: V iew View (Jsp and other clients) is responsible for the data display part
-
C: The Controller controller (Servlet) is responsible for the user interaction part of the application
- Three layer model
- On the basis of Model 2, the Model layer is divided into dao layer, entity layer and service layer
Spring MVC execution process
The following components are involved in spring MVC execution
-
Front end controller (dispatcher servlet)
It is responsible for receiving the client's request and calling other components to process the user's request, which reduces the coupling between components
-
Handler mapping
Responsible for finding the corresponding Handler to handle the request according to the user request.
-
Handler adapter
Through it, the processor is executed
-
Handler
Process request, return to logical view
-
View Resolver
It is responsible for resolving the logical View to the physical View address (i.e. page address), generating the View view, rendering the View and displaying it on the client
-
View (view)
Client page
Execution process
DispatcherServlet receives the request -- > handlermapping maps out the corresponding handler -- > handleadapter adapts the real processor through the adapter to process the request -- > handler processes the request, returns modelandview -- > DispatcherServlet accepts modelandview -- > View resolver processes the view, obtains the logical view, and resolves it into the physical view -- > DispatcherServlet requests render view -- > * * view for render view * * --- DispatcherServlet responds back to the client
[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-I70Ayuis-1584420553015)(img\SpringMVC principle. png))
Spring MVC use
pom.xml dependency
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.4.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
Configure web.xml
After importing dependencies, configure the front-end controller components in web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <!-- Program entry loading spring Of xml To configure --> <web-app> <!-- When the monitor is on top, web-app If there is a mistake, write the following web-app <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"> --> <display-name>Archetype Created Web Application</display-name> <!-- Load Spring Related profile --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-*.xml</param-value> </context-param> <!-- spring Other configuration: do not put it on the top, if there is a filter, put it behind the filter --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- To configure SpringMVC Configuration: DispatcherServlet--> <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:spring-mvc.xml</param-value> </init-param> <!-- To configure DispatcherServlet Priority loading --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Front end controller configuration considerations
Note that also set the contextConfigLocation of the dispatcher Servlet
If this property is not set, Spring MVC will automatically look up * * [servlet name] - servlet.xml file under WEB-INF as the configuration file of Spring MVC**
If there is no configuration, you need to create a new file named: [servlet name] - servlet.xml under / WEB-INF
**What [servlet name] refers to**
XML mode
Configure spring-mvc.xml
spring-mvc.xml (the XML name can be customized, and the classpath can be configured according to the web context)
-
Internal resource view resolver: View resolver. Prefix and suffix can be configured respectively in this attribute. To ensure the security of the program, the page can be placed under / WEB-INF / filename /.
- Prefix: if this property is not configured, the prefix is /, which represents the webapp directory
- suffix: can be set to. jsp or. html as required by the project
- < context: annotation config / >. If there is a context: component scan configuration, this configuration will not be used.
- MVC: default servlet handler: default servlet processor. This configuration can ensure that Spring MVC project can directly access static resources, such as index.html
- MVC: annotation driven: annotation driver, which enables the current project to use annotations to complete the configuration. For example: @ Controller
- Context: Component scan: the package scanning Component of the context. With this configuration, all the packages corresponding to the basePackage can be directly scanned for use by adding * * @ Component, @ Repository, @ Service, @ Controller @RestController, @ControllerAdvice, and @Configuration * components above the class
<! -- configure view parser -- > <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <! -- configure the defau lt servlet processor, static resources can be accessed directly; if not configured, static pages cannot be accessed -- > <mvc:default-servlet-handler/> <! -- front end controller, which static resources are not intercepted -- > <mvc:resources location="/css/" mapping="/css/**"/> <mvc:resources location="/images/" mapping="/images/**"/> <mvc:resources location="/js/" mapping="/js/**"/> <! -- spring MVC in XML mode The id attribute value of a bean cannot contain special characters Name is OK, so the path needs to use name to identify the path of a controller Here name is the url path of client access, and will jump to the corresponding class after access --> <bean name="/productInput" class="com.qf.controller.ProductInputController"/> <bean name="/saveProduct" class="com.qf.controller.SaveProductController"/>
Example
ProductInputController implementation class 1
public class ProductInputController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { // A logical view will be returned return new ModelAndView("index"); } }
WEB-INF/pages/index.jsp
<form method="post" action="saveProduct"> pid:<input type="text" name="pid" /><br /> pname:<input type="text" name="pname" /><br /> price:<input type="text" name="price" /><br /> <input type="submit" value="submit" /><br /> </form>
SaveProductController implementation class 2
public class SaveProductController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { String pid = req.getParameter("pid"); String pname = req.getParameter("pname"); String price = req.getParameter("price"); Product p = new Product(); p.setPid(pid); p.setPname(pname); p.setPrice(price == null? 0.0:Double.parseDouble(price)); ModelAndView mv = new ModelAndView("success","p",p); // Return to the logical view and pass the object back to the front end; //Equivalent to req.getRequestDispatcher().forward() and req.setAttribute() return mv; } }
success.jsp
<h3>pId: ${p.pid}</h3> <h3>pId: ${p.pname}</h3> <h3>pId: ${p.price}</h3>
Annotation mode
Configure spring-mvc.xml
spring-mvc.xml (the XML name can be customized, and the classpath can be configured according to the web context)
<! -- configure view parser -- > <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> <! -- configure the defau lt servlet processor, static resources can be accessed directly; if not configured, static pages cannot be accessed -- > <mvc:default-servlet-handler/> <! -- enable SringMVC annotation -- > <mvc:annotation-driven />
Common annotations
@RequestMapping
-
Function: establish the corresponding relationship between url and controller processing method
- Act on class
- Act on method
-
Property (optional /)
- Path: Specifies the url of the request path
- Value: the value attribute is the same as the path attribute
- mthod: specify the request method of the method
-
Code:
@RequestMapping("anno") public class RequestController { @RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String body){ System.out.println(body);// username=root&uid=123 return "success"; } @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ ModelAndView mav = new ModelAndView(); User user = new User(); user.setUname("distance"); user.setUid("55"); mav.addObject("user",user); mav.setViewName("show"); return mav; } }
@RequestParam
-
Role: pass the parameter with the name specified in the request to the parameter in the controller (the request name can be different from the controller parameter name)
-
attribute
- value: the name of the request parameter
- required: whether the request parameter must be provided. The default is true (must be provided)
- defaultvalue: set the default value
-
Code
// If the parameter is the basic data type and String, you can not add @ RequestParam // @RequestParam: if the parameter passed by the client is different from the background parameter name, this annotation can be used // @RequestParam(required = false) can be modified without passing values. By default, parameters must be passed public String testRequestParam(@RequestParam(name = "name") String uname){ System.out.println("This is the test. RequestParam()-->name: "+uname);// This is the test requestparam() -- > Name: ha ha return "success"; } public String testRequestParam( String name){}
@RequestBody
-
Function: used to get the content of the request body (Note: get method is not allowed)
-
attribute
- required: whether there must be a request body. The default value is true
-
Code
@RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String body){ System.out.println(body);// username=root&uid=123 return "success"; }
@GetMapping
-
Function: accept the request of get method, and do not accept post data
-
Properties:
- value: the name of the request parameter
-
Code
@GetMapping("/saveStu") public ModelAndView saveStu(){ return new ModelAndView("validate","student",new Student()); }
@PostMapping
-
Function: accept post request and accept data
-
Properties:
- value: the name of the request parameter
-
Code
@PostMapping("/saveStu") public String saveStu(@ModelAttribute Student student, BindingResult errors, Model model) { StuValidate sv = new StuValidate(); sv.validate(student, errors); // If there is an error message in the error set if (errors.hasErrors()) { // Return the information entered by the front end to the front end model.addAttribute("student", student); return "validate"; } return "success"; }
@RestController
It is used to annotate a bean. It has the same function as @ Component. It is generally used to annotate before and after separation. When data is returned, the returned data will be automatically converted to json format. After using this annotation, it is equivalent to using * * @ Controller+@ResponseBody * *, but @ Controller belongs to front end and back end.
@RequestMapping("/del/{id}") public boolean delBook(@PathVariable Integer id){ // Convert boolean to json string format and send it back to the front end return bookService.delBookService(id); } @RequestMapping("/list") public List<Book> listBook(){ // Convert the list set to json string format and send it back to the front end return bookService.detailBookService(); }
@Controller
It is used to annotate a bean. It has the same function as @ Component. It is generally used when the front and back ends are not separated. Only when it is used with @ ResponseBody, the returned data will be automatically converted to json format.
Without @ ResponseBody
@RequestMapping("/getAdmin") public String getAdmin(HttpSession session,Model model){ String admin = (String)session.getAttribute("admin"); model.addAttribute("list",adminService.getAdminByNameService(admin)); // A logical view is returned return "adminUdp.jsp"; }
Add @ ResponseBody
@RequestMapping("/list") @ResponseBody public List<Admin> adminList(HttpSession session){ String admin = (String)session.getAttribute("admin"); // Here is a list data in the form of json string return adminService.getAdminByNameService(admin); }
File upload
Configuring in spring-mvc.xml
<! -- profile upload parser object -- > <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <! -- limit file upload size -- > <property name="maxUploadSize" value="10485760"/> </bean>
Controller
@RequestMapping("/testFileUpload") public String testFileUpload(@RequestParam String name, MultipartFile upload, HttpServletRequest req) throws IOException { System.out.println("Start uploading"); // Upload location String path = req.getSession().getServletContext().getRealPath("/upload"); // Determine whether the path exists File file = new File(path); if(!file.exists()){ file.mkdirs(); } // Get upload file name String filename = upload.getOriginalFilename(); String uuid = UUID.randomUUID().toString().replace("-", ""); filename = uuid+"_"+filename; // Finish uploading upload.transferTo(new File(file,filename)); System.out.println(name); return "show"; }
Custom exception
Configuring in spring-mvc.xml
<!--Configure exception handler--> <bean id="exceptionResolver" class="com.qf.exception.MyExceptionResolver"/>
Custom exception class
public class MyException extends Exception{ private String message; public MyException(String message) { this.message = message; } @Override public String getMessage() { return super.getMessage(); } public void setMessage(String message) { this.message = message; } }
Exception implementation class
public class MyExceptionResolver implements HandlerExceptionResolver { /** * * @param req * @param resp * @param handler * @param ex Custom exception * @return */ @Override public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) { MyException e = null; if (ex instanceof MyException) { e = (MyException) ex; // e = new MyException("system crash, please visit later! ""; }else{ e = new MyException("System crash, please visit later!"); } ModelAndView mav = new ModelAndView(); mav.addObject("errMsg",e.getMessage()); mav.setViewName("error"); return mav; }
Controller
@RequestMapping("/testExcpetion") public String testExcpetion() throws MyException { System.out.println("testExcpetion...."); try { int i = 10 / 0; } catch (Exception e) { e.printStackTrace(); throw new MyException("exception occurred"); } return "error"; }
custom interceptor
Configuring in spring-mvc.xml
<!-- Configure custom interceptors --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/demo/*"/> <bean id="myInterceptor" class="com.qf.interceptor.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
Custom interceptor class
/** Intercepts the specified methods under the path of xml configuration */ public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle Preprocessing controller Before execution"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle Postprocessing controller After execution"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion After page execution "); } }
affair
pom.xml
<dependency> <groupId>org.aspectj</groupId> <artifactId>com.springsource.org.aspectj.weaver</artifactId> <version>1.6.8.RELEASE</version> </dependency>
spring-mybatis.xml
<!-- Configure transaction manager --> <bean id="dtx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="ds" /> </bean> <!-- Declare how transactions are implemented The methods starting with these keywords set the isolation level of the transaction and the operation after the error respectively --> <tx:advice transaction-manager="dtx" id="tx"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="Exception"/> <tx:method name="insert*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="Exception"/> <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="Exception"/> <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" rollback-for="Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="mpt" expression="execution(* com.qfedu.service.*.*(..))" /> <aop:advisor advice-ref="tx" pointcut-ref="mpt" /> </aop:config>