14 top Spring MVC tips! Have you mastered it all

1. Use @Controller stereotype

This is the easiest way to create a controller class that can handle one or more requests. Just by annotating a class with a stereotype @Controller , for example:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
    @RequestMapping("/")
    public String visitHome() {
      
        return "home";
    }
}

 

As you can see, the visitHome() method handles requests from the application context path (/) by redirecting to the view named home.

Note: The @Controller prototype can only be used when annotation-driven is enabled in the Spring configuration file:

<annotation-driven />

 

When annotation-driven is enabled, the Spring container automatically scans classes under the package specified by the following statement:

 

<context:component-scan base-package="net.codejava.spring" />

 

@Controller The class annotated by the annotation is configured as a controller. This is the most desirable because it is simple: no need to declare beans for the controller in the configuration file.

Note: By using @Controller annotations, you can have a multi-action controller class that can handle multiple different requests. E.g:

@Controller
public class MultiActionController {
    @RequestMapping("/listUsers")
    public ModelAndView listUsers() {
    }
    @RequestMapping("/saveUser")
    public ModelAndView saveUser(User user) {
    }
    @RequestMapping("/deleteUser")
    public ModelAndView deleteUser(User user) {
    }
}

 

As you can see above controller class, there are three kinds of processing three different request processing method    /listUsers, /saveUser, and /deleteUser, respectively.

 

2. Implement the controller interface

Another (perhaps classic) way to create a controller in Spring MVC is to let the class implement the   Controller interface. E.g:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class MainController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        System.out.println("Welcome main");
        return new ModelAndView("main");
    }
}

 

The implementation class must override this   handleRequest() method. When a matching request comes in, this method will be called by the Spring scheduler Servlet. The request URL pattern processed by this controller is defined in Spring's context configuration file as follows:

 

<bean name="/main" class="net.codejava.spring.MainController" />

 

However, the disadvantage of this method is that the controller class cannot handle multiple request URLs.

 

3. Extend the AbstractController class

If you want to easily control the supported HTTP methods, sessions and content caching. Extending your controller   AbstractController class is ideal. Consider the following example:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class BigController extends AbstractController {
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        System.out.println("You're big!");
        return new ModelAndView("big");
    }
}

 

This will create a single-action controller with configurations about supported methods, sessions, and caches, which can then be specified in the controller's bean declaration. E.g: 

 

<bean name="/big" class="net.codejava.spring.BigController">
    <property name="supportedMethods" value="POST"/>
</bean>

 

This configuration indicates that POST this controller's hander method only supports that method.

Spring MVC also provides several controller classes designed for specific purposes, including:

  • AbstractUrlViewController

  • MultiActionController

  • ParameterizableViewController

  • ServletForwardingController

  • ServletWrappingController

  • UrlFilenameViewController

 

4. Specify URL mapping for handler method

This is a mandatory task that must be performed when coding a controller class designed to handle one or more specific requests. Spring MVC provides @RequestMapping annotations that are used to specify URL mapping. E.g:

@RequestMapping("/login")

 

This maps the /login URL pattern to be handled by the annotated method or class. When this annotation is used at the class level, the class will become a single-action controller. E.g:

 

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/hello")
public class SingleActionController {
    @RequestMapping(method = RequestMethod.GET)
    public String sayHello() {
        return "hello";
    }
}

 

When @RequestMapping annotations are used at the method level, you can have a multi-action controller. E.g:

 

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
    @RequestMapping("/listUsers")
    public String listUsers() {
        return "ListUsers";
    }
    @RequestMapping("/saveUser")
    public String saveUser() {
        return "EditUser";
    }
    @RequestMapping("/deleteUser")
    public String deleteUser() {
        return "DeleteUser";
    }
}

 

The @RequestMapping annotation can also be used to specify multiple URL patterns to be processed by a method. E.g:

@RequestMapping({"/hello", "/hi", "/greetings"})

 

In addition, this annotation also has other attributes that may be useful in certain situations, for example method.

 

5. Specify the HTTP request method for the handler method

Annotated method attributes can be used to specify which HTTP methods (GET, POST, PUT, etc.) the handler method supports.   @RequestMapping。This is an example:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class LoginController {
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String viewLogin() {
        return "LoginForm";
    }
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String doLogin() {
        return "Home";
    }
}

 

This controller has two methods for handling the same URL pattern /login, but the former is used for   GET methods and the latter is used for   POST methods. For @RequestMapping more information on using annotations, see @RequestMapping annotation.

 

6. Map request parameters to handler methods

One of the cool features of Spring MVC is that you can use @RequestParam annotations to retrieve request parameters as regular parameters of the handler method. This is HttpServletRequest a good way to separate the controller from the Servlet API interface.

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String doLogin(@RequestParam String username,
                      @RequestParam String password) {
}

 

Spring binds the method parameters username and password to HTTP request parameters with the same name. This means that you can call the URL as follows (if the request method is GET):

 

http:// localhost:8080 / spring / login?username = scott&password = tiger

 

Type conversion is also done automatically. For example, if you declare the integer following types of parameters:

 

@RequestParam int securityNumber

 

Then, Spring will automatically convert the value of the request parameter (string) to the specified type (integer) in the handler method.

If the parameter name is different from the variable name, you can specify the actual name of the parameter as follows:

@RequestParam("SSN") int securityNumber

 

The @RequestParam annotation also has two additional attributes, which may be useful in certain situations. This attribute specifies whether the parameter is required. E.g: required 

 

@RequestParam(required = false) String country

This means that the parameter   country is optional; therefore, it may be lost from the request. In the example above, country if no such parameter exists in the request, the variable will be null.

Another attribute is   defaultValuethat it can be used as a fallback value when the request parameter is empty. E.g:

@RequestParam(defaultValue = "18") int age

 

Map If the method parameter is type, Spring also allows us to access all parameters as objects   Map<String, String>. E.g:

 

doLogin(@RequestParam Map<String, String> params)

Then, the mapping parameters include all request parameters in the form of key-value pairs. For @RequestParam more information on using annotations, see @RequestParam annotation. Pay attention to the WeChat public account: Java technology stack, and reply in the background: spring, you can get the N latest Spring tutorials I have compiled, all of which are dry goods.

7. Return to model and view

After processing the business logic, the handler method should return a view, which is then parsed by Spring's scheduler servlet. Spring allows us  to return String or Object ModelAndView from handlermethod.

In the following example, the   handler method returns a String and represents a view named   LoginForm:

@RequestMapping(value = "/login", method = RequestMethod.GET)
public String viewLogin() {
    return "LoginForm";
}

 

This is the easiest way to return the name of the view. However, if you want to send other data to the view, you must return an   ModelAndView object. Consider the following handler method:

 

@RequestMapping("/listUsers")
public ModelAndView listUsers() {
    List<User> listUser = new ArrayList<>();
    // 从DAO获取用户列表…
    ModelAndView modelView = new ModelAndView("UserList");
    modelView.addObject("listUser", listUser);
    return modelView;
}

 

As you can see, this handler method returns an  object that   ModelAndView holds the name UserList of the view   Userand a collection of objects that can be used in the view.

Spring is also very flexible, because you can ModelAndView declare objects as parameters of handler methods instead of creating a new object. Therefore, the above example can be rewritten as follows:

@RequestMapping("/listUsers")
public ModelAndView listUsers(ModelAndView modelView) {
    List<User> listUser = new ArrayList<>();
    //从DAO获取用户列表…
    modelView.setViewName("UserList");
    modelView.addObject("listUser", listUser);
    return modelView;
}

 

For more information about this class, see: ModelAndView class. 

 

8. Put the object into the model

In applications that follow the MVC architecture, the controller (C) should pass data to the model (M), and then use the model in the view (V). As we saw in the previous example, the addObject() methods   ModelAndViewof this class put objects in the model in the form of name-value pairs:

modelView.addObject("listUser", listUser);
modelView.addObject("siteName", new String("CodeJava.net"));
modelView.addObject("users", 1200000);

Likewise, Spring is very flexible. You can Map declare type parameters in the handler method. Spring uses this mapping to store the objects of the model. Let's look at another example:

@RequestMapping(method = RequestMethod.GET)
public String viewStats(Map<String, Object> model) {
    model.put("siteName", "CodeJava.net");
    model.put("pageviews", 320000);
    return "Stats";
}

 

This is ModelAndView simpler than using objects. Depending on your preference, you can use Map or use   ModelAndView objects. I would like to thank Spring for its flexibility. 

 

9. Redirection in handler method

If you want to redirect the user to another URL when the conditions are met, please redirect:/ append before the URL. The following code snippet gives an example:

// 检查登录状态....
if (!isLogin) {
    return new ModelAndView("redirect:/login");
}
// 返回用户列表

 

In the above code, /login if not logged in, the user will be redirected to that URL. 

 

10. Processing form submission and form verification

 Spring makes it easy to handle form submissions by providing @ModelAttribute annotations BindingResultfor binding form fields to form support objects and an interface for validating form fields. The following code snippet shows a typical handler method, which is responsible for processing and validating form data:

@Controller
public class RegistrationController {
    @RequestMapping(value = "/doRegister", method = RequestMethod.POST)
    public String doRegister(
        @ModelAttribute("userForm") User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            // 表单验证错误
        } else {
            // 表单输入没问题
        }
        // 注册过程……
        return "Success";
    }
}

 

Learn more about @ModelAttribute annotations and BindingResult interfaces from Spring's official documentation :

  • Use @ModelAttribute on method parameters

  • Use @ModelAttribute on the method

  • Interface binding result

 

11. Process file upload

By automatically binding upload data to CommonsMultipartFile an array of objects, Spring also makes it easy to handle file uploads in handler methods. Spring uses Apache Commons FileUpload as the basic multi-part parser.

The following code snippet shows how easy it is to upload files from the client

@RequestMapping(value = "/uploadFiles", method = RequestMethod.POST)
public String handleFileUpload(
        @RequestParam CommonsMultipartFile[] fileUpload) throws Exception {
    for (CommonsMultipartFile aFile : fileUpload){
        // 存储上传的文件
        aFile.transferTo(new File(aFile.getOriginalFilename()));
    }
    return "Success";
}

 

12. Automatically assemble business classes in the controller

The controller should delegate the processing of business logic to the relevant business class. For this, you can use @Autowired annotations to let Spring automatically inject the actual implementation of the business class into the controller. Pay attention to the WeChat public account: Java technology stack, reply in the background: sp, you can get the N latest Spring Boot tutorials I have compiled, all of which are dry goods.

Consider the following code snippet for the controller class:

@Controller
public class UserController {
    @Autowired
    private UserDAO userDAO;
    public String listUser() {
        // 列出所有用户的处理方法
        userDAO.list();
    }
    public String saveUser(User user) {
        // 保存/更新用户的处理方法
        userDAO.save(user);
    }
    public String deleteUser(User user) {
        // 删除用户的处理方法
        userDAO.delete(user);
    }
    public String getUser(int userId) {
        // 获取用户的处理方法
        userDAO.get(userId);
    }
}

 

Here, all business logic related to user management is UserDAO provided by the implementation of this interface. E.g:

 

interface UserDAO {
    List<User> list();
    void save(User user);
    void checkLogin(User user);
}

 

For @Autowired more information about the attention solution, see Note Type Automatic Assembly.

 

13.访问HttpServletRequest和HttpServletResponse

In some cases, you need to access the HttpServletRequest or   HttpServletResponseobject directly in the handler method   .

With Spring's flexibility, you only need to add relevant parameters to the processing method. E.g:

@RequestMapping("/download")
public String doDownloadFile(
        HttpServletRequest request, HttpServletResponse response) {
    // 访问请求
    // 访问响应
    return "DownloadPage";
}

 

Spring detects and automatically    injects the HttpServletRequest sum   HttpServletResponseobject into the method. Then, you can access the request and response such as get   InputStream,   OutputStreamor return a specific HTTP code.

 

14. Follow the single responsibility principle

Finally, when designing and writing Spring MVC controllers, there are two good practices you should follow:

1) The controller class should not execute business logic. Instead, it should delegate business processing to related business categories. This allows the controller to always focus on its design responsibility to control the workflow of the application. E.g:

 

@Controller
public class UserController {
    @Autowired
    private UserDAO userDAO;
    public String listUser() {
        userDAO.list();
    }
    public String saveUser(User user) {
        userDAO.save(user);
    }
    public String deleteUser(User user) {
        userDAO.delete(user);
    }
    public String getUser(int userId) {
        userDAO.get(userId);
    }
}

 

2) Create each individual controller for each business domain. For example, it is   UserController used to control the OrderController workflow of user management and the workflow of order processing. E.g:

 

@Controller
public class UserController {
}
@Controller
public class ProductController {
}
@Controller
public class OrderController {
}
@Controller
public class PaymentController {
}

 

These 14 tips can help you write controller classes in Spring MVC correctly and effectively. If you have other tips or suggestions, please feel free to share your thoughts in the comments.

Guess you like

Origin blog.csdn.net/bjmsb/article/details/109301096