springMVC exception interceptor file upload

Keywords: JSP REST JSON Javascript

Asynchronous call

Send asynchronous requests (review)

<a href="javascript:void(0);" id="testAjax">Visit controller</a>
<script type="text/javascript" src="/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    $(function(){
    $("#testAjax").click(function(){ //Bind click events for components with id="testAjax"
        $.ajax({ //Send Asynchronous Call
            type:"POST", //Request method: POST request
            url:"ajaxController", //Request parameters (that is, request content)
            data:'ajax message', //Request parameters (that is, request content)
            dataType:"text", //Response Body Type
            contentType:"application/text", //MIME type of request body
        });
    });
});
</script>

Accept asynchronous request parameters

_Name: @RequestBody
Type: Parametric Notes
Location: Method parameter front in processor class
Role: Organize asynchronous submission data into a standard request parameter format and assign it to a parameter
Example:

@RequestMapping("/ajaxController")
public String ajaxController(@RequestBody String message){
    System.out.println(message);
    return "page.jsp";
}  
  • When an annotation is added in front of a Pojo parameter, the encapsulated asynchronous submission data is mapped to a relationship in Pojo's attribute format
  • When an annotation is added in front of a collection parameter, the encapsulated asynchronous commit data is mapped relative to the storage structure of the collection
@RequestMapping("/ajaxPojoToController")
//If the processing parameter is POJO and the request data format sent by the page corresponds to the attributes in the POJO, the @RequestBody annotation can automatically map the corresponding request data to the POJO
//Note: Attributes in POJO are not mapped if they are not in the request data, the attribute value is null, and attributes not in POJO are not mapped if they are in the request data
public String  ajaxPojoToController(@RequestBody User user){
    System.out.println("controller pojo :"+user);
    return "page.jsp";
}

@RequestMapping("/ajaxListToController")
//If the processing parameter is a List collection and POJO is encapsulated, and the data sent by the page is an array of objects in JSON format, the data is automatically mapped to the collection parameter
public String  ajaxListToController(@RequestBody List<User> userList){
    System.out.println("controller list :"+userList);
    return "page.jsp";
}

Asynchronous request acceptance response data

  • Auto-encapsulate data into json object data when method returns Pojo
@RequestMapping("/ajaxReturnJson")
@ResponseBody
public User ajaxReturnJson(){
    System.out.println("controller return json pojo...");
    User user = new User();
    user.setName("Jockme");
    user.setAge(40);
    return user;
}  
  • Automatically encapsulates data into a json object array when the method returns a List
@RequestMapping("/ajaxReturnJsonList")
@ResponseBody
//Based on jackon technology, the @ResponseBody annotation can be used to convert the returned collection of saved POJO objects into json array format data
public List ajaxReturnJsonList(){
    System.out.println("controller return json list...");
    User user1 = new User();
    user1.setName("Tom");
    user1.setAge(3);

    User user2 = new User();
    user2.setName("Jerry");
    user2.setAge(5);

    ArrayList al = new ArrayList();
    al.add(user1);
    al.add(user2);

    return al;
}

Asynchronous Request-Cross Domain Access

Introducing Cross-Domain Access

  • When accessing resources under domain name B through operations under domain name A, this is called cross-domain access
  • Unaccessible when accessing across domains

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-QanwYgAv-1593133079432) (day02.assets/image-202004271626591.png)]

2.2 Building Cross-domain Environment

  • Add an alternate domain name for the current host
    • Modify the host file in the windows installation directory
    • Format: ip domain name
  • Dynamic Refresh DNS
    • Command: ipconfig/displaydns
    • Command: ipconfig/flushdns

Cross-domain access support

_Name: @CrossOrigin
Type: method annotation, class annotation
Location: above or above a method in a processor class
Role: Set all methods in the current processor method/processor class to support cross-domain access
Example:

@RequestMapping("/cross")
@ResponseBody
//Open cross-domain access using @CrossOrigin
//Labels above processor methods indicate that the method supports cross-domain access
//Labeled above the processor class indicates that all processor methods in the processor class support cross-domain access
@CrossOrigin
public User cross(HttpServletRequest request){
    System.out.println("controller cross..."+request.getRequestURL());
    User user = new User();
    user.setName("Jockme");
    user.setAge(39);
    return user;
}

Interceptor

Interceptor concepts

  • Request Processing Resolution

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-VhI2Nhg5-1593133079435)(day02.assets/image-20200427164038103.png)]

Interceptor is a mechanism for intercepting method calls dynamically
Effect:

  	1. Execute pre-set code before and after the specified method call
 	2. Prevent the execution of the original method

Core Principle: AOP Thought
Interceptor Chain: Multiple interceptors enhance the original invoked function in a certain order

  • Interceptor VS Filter
    Different attribution: Filter belongs to Servlet technology, Interceptor belongs to SpringMVC Technology
    Interceptor content is different: Filter enhances all access, Interceptor enhances only SpringMVC access

    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-86iQYjMx-1593133079437)(day02.assets/image-20200427164512745.png)]

Custom interceptor development process

  • Implement HandlerInterceptor interface

    //Custom interceptors need to implement the HandleInterceptor interface
    public class MyInterceptor implements HandlerInterceptor {
        //Execute before processor runs
        @Override
        public boolean preHandle(HttpServletRequest request,
                                 HttpServletResponse response,
                                 Object handler) throws Exception {
            System.out.println("Pre-run----a1");
            //A return value of false will block the original processor from running
            //If multiple interceptors are configured, a return value of false will terminate the operation of the interceptor configured behind the current interceptor
            return true;
        }
    
        //Execute after processor runs
        @Override
        public void postHandle(HttpServletRequest request,
                               HttpServletResponse response,
                               Object handler,
                               ModelAndView modelAndView) throws Exception {
            System.out.println("Post-run----b1");
        }
    
        //After all interceptors'rear execution is complete, perform the operation
        @Override
        public void afterCompletion(HttpServletRequest request,
                                    HttpServletResponse response,
                                    Object handler,
                                    Exception ex) throws Exception {
            System.out.println("Complete Running----c1");
        }
    
        //The three methods run in the order preHandle -> postHandle -> afterCompletion
        //If preHandle returns false, the three methods only run preHandle
    }
    
  • Configuring Interceptors

    Configuring Interceptors

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/showPage"/>
        <bean class="com.itheima.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

Note: The order of configuration is to configure the execution location before configuring the execution class

Interceptor Execution Process

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-SRQgzt2g-1593133079439)(day02.assets/image-20200427164840131.png)]

Interceptor configuration and method parameters

Pre-processing method

Run before original method

public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler) throws Exception {
    System.out.println("preHandle");
    return true;
}
  • parameter
    request: request Object
    response: response Object
    handler: The called processor object, essentially a method object, repackages the Method object in the reflection
  • Return value
    The return value is false, the intercepted processor will not execute

Post-processing method

Runs after the original method runs, but does not execute if the original method is intercepted

public void postHandle(HttpServletRequest request,
                       HttpServletResponse response,
                       Object handler,
                       ModelAndView modelAndView) throws Exception {
    System.out.println("postHandle");
}

Parameters
_modelAndView: If processor execution completes with a return result, the corresponding data and page information can be read and adjusted

Complete Processing

The last method executed by the interceptor, whether or not the original method is executed

public void afterCompletion(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            Exception ex) throws Exception {
    System.out.println("afterCompletion");
}

Parameters
_ex: If an exception object occurs during processor execution, it can be handled separately for the exception

Interceptor Configuration Items

<mvc:interceptors>
    <!--Turn on the use of specific interceptors to configure mu lt iple -->
    <mvc:interceptor>
        <!--Set the interceptor's intercept path, support*wildcard-->
        <!--/** means intercepting all mappings-->
        <!--/* means intercepting all/beginning mappings-->
        <!--/user/* means intercepting all/user/start mappings-->
        <!--/user/add* means intercept all/user/start maps with specific map names beginning with add-->
        <!--/user/*All means intercept all/user/start mappings with specific mapping names ending with All-->
        <mvc:mapping path="/*"/>
        <mvc:mapping path="/**"/>
        <mvc:mapping path="/handleRun*"/>
        <!--Set the path to intercept exclusion, configure /** or /*, for quick configuration purposes-->
        <mvc:exclude-mapping path="/b*"/>
        <!--Specify specific interceptor class-->
        <bean class="MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

Multiple Interceptor Configuration

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-90rwc1DW-1593133079440) (day02.assets/image-202004271722781.png)]

Responsibility chain model
Responsibility chain model is a behavior model
Features:
Executes in a predefined sequence of tasks, with each node having its own work task
Advantages:
Independence: Focus solely on the tasks of the current node and release directly to the next node for other tasks
Isolation: Chain transfer feature, no need to know the overall link structure, just wait for the request to arrive and process
Flexibility: Link structure can be modified at will to dynamically add or remove overall link responsibility
Decouple: Decouple dynamic tasks from original tasks
Disadvantages:
Processing efficiency is low when the link is too long
There may be circular references on nodes, causing an endless loop and causing the system to crash

exception handling

Exception Handler

HandlerExceptionResolver interface (exception handler)

@Component
public class ExceptionResolver implements HandlerExceptionResolver {
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler,
                                         Exception ex) {
        System.out.println("Exception Processor Executing");
        ModelAndView modelAndView = new ModelAndView();
        //Define information that is fed back to the user when an anomaly occurs
        modelAndView.addObject("msg","Error! ");
        //Define pages that users will see when an exception occurs
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
}

Manage exceptions by category and return different information depending on the type of exception

public class ExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler,
                                         Exception ex) {
        System.out.println("my exception is running ...."+ex);
        ModelAndView modelAndView = new ModelAndView();
        if( ex instanceof NullPointerException){
            modelAndView.addObject("msg","Null pointer exception");
        }else if ( ex instanceof  ArithmeticException){
            modelAndView.addObject("msg","Arithmetic operation exception");
        }else{
            modelAndView.addObject("msg","Unknown exception");
        }
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
}

Annotation Development Exception Handler

  • Using annotations for exception classification management
    _Name: @ControllerAdvice
    Type: Class Notes
    Location: Above the exception handler class
    Roles: Sets the current class to the exception handler class
    Example:
@Component
@ControllerAdvice
public class ExceptionAdvice {
}  
  • Using annotations for exception classification management
    _Name: @ExceptionHandler
    Type: Method Notes
    Location: Above the methods in the exception handler class that handle the specified exception
    Roles: Sets how specified exceptions are handled
    Example:
    Note: Processor methods can be set to multiple
@ExceptionHandler(Exception.class)
@ResponseBody
public String doOtherException(Exception ex){
   return "Error, please contact the administrator! ";
}  

Exception Handling Solutions

  • Exception handling scheme
    • Business exceptions:
      Send corresponding message to user to remind specification operation
    • System exception:
      Send fixed messages to users to soothe them
      Send specific messages to maintenance personnel to remind them of maintenance
      Logging
    • Other exceptions:
      Send fixed messages to users to soothe them
      Send specific messages to programmers to remind them of maintenance
      Include in Expected Scope
      Logging

Custom Exception

  • Exception Definition Format

    //Custom exceptions inherit RuntimeException, overriding all construction methods of the parent class
    public class BusinessException extends RuntimeException {
        public BusinessException() {
        }
    
        public BusinessException(String message) {
            super(message);
        }
    
        public BusinessException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public BusinessException(Throwable cause) {
            super(cause);
        }
    
        public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }
    }
    
  • Exception Trigger Mode

    if(user.getName().trim().length()<4) {
        throw new BusinessException("User name length must be 2-4 Between bits, please re-enter! ");
    }
    
  • Classify and manage all anomalies by custom anomalies to present anomaly messages in a uniform format

Practical Technology

File upload and download

  • Upload File Process Analysis

    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-ywrst9uM-1593133079441)(day02.assets/image-20200427174442939.png)]

  • MultipartResolver interface

    • The MultipartResolver interface defines the operations associated with file uploading and encapsulates the common operations
    • MultipartResolver interface underlying implementation class CommonsMultipartResovler
    • CommonsMultipartResovler does not implement the function of file upload and download on its own. Instead, it calls apache's file upload and download component
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    
  • File Upload and Download Implementation

    • Page Form

      <form action="/fileupload" method="post" enctype="multipart/form-data">
          Upload LOGO:<input type="file" name="file"/><br/>
          <input type="submit" value="upload"/>
      </form>
      
    • Spring MVC Configuration

      <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      </bean>
      
    • Controller

      @RequestMapping(value = "/fileupload")
      public void fileupload(MultipartFile file){
          file.transferTo(new File("file.png"));
      }
      

Notes on file upload

  1. File Naming Problem, Get Uploaded File Name, and Resolve File Name and Extension
  2. File name is too long
  3. File Save Path
  4. Duplicate Name Problem
@RequestMapping(value = "/fileupload")
//The MultipartFile parameter is defined in the parameter to receive a form of type=file submitted by the page, requiring the form name to be the same as the parameter name
public String fileupload(MultipartFile file,MultipartFile file1,MultipartFile file2, HttpServletRequest request) throws IOException {
    System.out.println("file upload is running ..."+file);
    //        The MultipartFile parameter encapsulates information about the uploaded file
    //        System.out.println(file.getSize());
    //        System.out.println(file.getBytes().length);
    //        System.out.println(file.getContentType());
    //        System.out.println(file.getName());
    //        System.out.println(file.getOriginalFilename());
    //        System.out.println(file.isEmpty());
    //First determine if it is an empty file, which is a file with 0 storage space
    if(!file.isEmpty()){
        //If the size is handled properly within the scope requirements, otherwise a custom exception is thrown to inform the user (not implemented)
        //Get the name of the original uploaded file and save it as the real name of the current file in the database for later use
        String fileName = file.getOriginalFilename();
        //Set Saved Path
        String realPath = request.getServletContext().getRealPath("/images");
        //Save the file by specifying the location and name of the file. Normally, file names are generated using a random generation strategy to avoid file name conflicts
        file.transferTo(new File(realPath,file.getOriginalFilename()));
    }
    //Test uploading multiple files at once
    if(!file1.isEmpty()){
        String fileName = file1.getOriginalFilename();
        //You can distinguish different storage paths for different types of files and modify the corresponding storage location as needed.
        String realPath = request.getServletContext().getRealPath("/images");
        file1.transferTo(new File(realPath,file1.getOriginalFilename()));
    }
    if(!file2.isEmpty()){
        String fileName = file2.getOriginalFilename();
        String realPath = request.getServletContext().getRealPath("/images");
        file2.transferTo(new File(realPath,file2.getOriginalFilename()));
    }
    return "page.jsp";
}

Restful Style Configuration

Rest

  • Rest (REpresentational State Transfer) A style of accessing network resources that defines how they are accessed
    • Traditional style access path
       http://localhost/user/get?id=1
       http://localhost/deleteUser?id=1
    • Rest-style access path
       http://localhost/user/1
  • Restful accesses network resources in Rest style
  • Advantage
    Hide the access behavior of resources, and you can't tell what you're doing by address
    Writing Simplification

Rest behavior convention

GET (Query)Http://localhost/user/1GET
_POST (Save)Http://localhost/userPOST
PUT (Update)Http://localhost/userPUT
DELETE (Delete)Http://localhost/userDELETE
**Note: ** The above behavior is convention, convention is not a specification and can be broken, so it is called Rest style, not Rest specification

Getting Started with Restful Development

//Set rest style controller
@RestController
//Set up a public access path to use with the access path below
@RequestMapping("/user/")
public class UserController {

    //rest-style Access Path Complete Writing
    @RequestMapping("/user/{id}")
    //Use the @PathVariable annotation to get the named variable configured on the path that can be used multiple times
    public String restLocation(@PathVariable Integer id){
        System.out.println("restful is running ....");
        return "success.jsp";
    }

    //rest-style access paths simplify writing and are used with the class annotation @RequestMapping
    @RequestMapping("{id}")
    public String restLocation2(@PathVariable Integer id){
        System.out.println("restful is running ....get:"+id);
        return "success.jsp";
    }

    //Receive GET Request Configuration
    @RequestMapping(value = "{id}",method = RequestMethod.GET)
    //Receiving GET requests simplifies configuration
    @GetMapping("{id}")
    public String get(@PathVariable Integer id){
        System.out.println("restful is running ....get:"+id);
        return "success.jsp";
    }

    //Configuration method for receiving POST requests
    @RequestMapping(value = "{id}",method = RequestMethod.POST)
    //Receiving POST requests simplifies configuration
    @PostMapping("{id}")
    public String post(@PathVariable Integer id){
        System.out.println("restful is running ....post:"+id);
        return "success.jsp";
    }

    //Receiving PUT requests simplifies configuration
    @RequestMapping(value = "{id}",method = RequestMethod.PUT)
    //Receiving PUT requests simplifies configuration
    @PutMapping("{id}")
    public String put(@PathVariable Integer id){
        System.out.println("restful is running ....put:"+id);
        return "success.jsp";
    }

    //Receive DELETE requests to simplify configuration
    @RequestMapping(value = "{id}",method = RequestMethod.DELETE)
    //Receive DELETE requests to simplify configuration
    @DeleteMapping("{id}")
    public String delete(@PathVariable Integer id){
        System.out.println("restful is running ....delete:"+id);
        return "success.jsp";
    }
}
<!--Configure the interceptor, parse the parameters in the request_method, otherwise PUT requests and DELETE requests cannot be initiated for use with page forms-->
<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <servlet-name>DispatcherServlet</servlet-name>
</filter-mapping>

Turn on SpringMVC's Restful-style access support filter to submit PUT and DELETE requests through a page form
Page forms submit request types using hidden fields with parameter names fixed to _Method, must be used with submission type method=post

<form action="/user/1" method="post">
    <input type="hidden" name="_method" value="PUT"/>
    <input type="submit"/>
</form>  
  • Restful request path simplifies configuration

    @RestController
    public class UserController {
        @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
        public String restDelete(@PathVariable String id){
            System.out.println("restful is running ....delete:"+id);
            return "success.jsp";
        }
    }  
    

Installation and use of postman tools

Posman is a tool that can send Restful-style requests for development and debugging.First run requires networking registration

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-GHbE3Hwv-1593133079442)(day02.assets/image-20200427180851880.png)]

Posted by liquid79 on Thu, 25 Jun 2020 18:21:59 -0700