14 Essential Tips for Writing Spring MVC Controllers

This article presents fourteen practical techniques for building Spring MVC controllers, covering annotation usage, interface implementation, abstract class extension, URL mapping, HTTP method specification, request parameter binding, model handling, redirects, form processing, file uploads, dependency injection, servlet access, and single‑responsibility design.

Java Backend Technology
Java Backend Technology
Java Backend Technology
14 Essential Tips for Writing Spring MVC Controllers

In Spring MVC a controller class handles client requests, delegates business logic to service classes, and returns a logical view name that the DispatcherServlet resolves to render the result.

1. Use @Controller annotation

The simplest way to create a controller is to annotate a class with @Controller. Example:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
    @RequestMapping("/")
    public String visitHome() {
        return "home";
    }
}

When annotation‑driven configuration is enabled ( <annotation-driven/>) Spring scans the specified base package for such classes.

2. Implement the Controller interface

Another classic approach is to implement the Controller interface and override handleRequest:

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");
    }
}

Note that a class implementing this interface can handle only a single URL pattern.

3. Extend AbstractController

Extending AbstractController allows easy configuration of supported HTTP methods, session handling, and caching:

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");
    }
}

Bean definition can specify supported methods, e.g. supportedMethods="POST".

4. Specify URL mapping with @RequestMapping

The @RequestMapping annotation maps a URL pattern to a controller class or method:

@RequestMapping("/login")
public class LoginController { ... }

When placed at the class level the controller becomes a single‑action controller.

5. Define HTTP request method

Use the method attribute of @RequestMapping to restrict handling to specific HTTP verbs:

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

    @RequestMapping(method = RequestMethod.POST)
    public String doLogin() { return "Home"; }
}

6. Map request parameters with @RequestParam

Bind request parameters directly to method arguments:

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

Attributes such as required and defaultValue control validation and defaults.

7. Return ModelAndView

A handler can return a view name as a String or a ModelAndView object when additional data is needed:

@RequestMapping("/listUsers")
public ModelAndView listUsers() {
    List<User> list = new ArrayList<>(); // fetch from DAO
    ModelAndView mv = new ModelAndView("UserList");
    mv.addObject("listUser", list);
    return mv;
}

8. Put objects into the model

Use ModelAndView.addObject or a Map<String,Object> parameter to expose data to the view:

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

9. Perform redirects

Return a view name prefixed with redirect:/ to send the client to another URL:

if (!isLogin) {
    return new ModelAndView("redirect:/login");
}

10. Handle form submission with @ModelAttribute

Bind form fields to a command object and validate with BindingResult:

@Controller
public class RegistrationController {
    @RequestMapping(value="/doRegister", method=RequestMethod.POST)
    public String doRegister(@ModelAttribute("userForm") User user,
                             BindingResult result) {
        if (result.hasErrors()) {
            // handle errors
        }
        // registration logic
        return "Success";
    }
}

11. File upload handling

Spring binds uploaded files to CommonsMultipartFile[] parameters:

@RequestMapping(value="/uploadFiles", method=RequestMethod.POST)
public String handleFileUpload(@RequestParam CommonsMultipartFile[] fileUpload) throws Exception {
    for (CommonsMultipartFile f : fileUpload) {
        f.transferTo(new File(f.getOriginalFilename()));
    }
    return "Success";
}

12. Autowire business classes

Inject service or DAO beans into a controller with @Autowired:

@Controller
public class UserController {
    @Autowired
    private UserDAO userDAO;

    public String listUser() { userDAO.list(); }
    public String saveUser(User u) { userDAO.save(u); }
    public String deleteUser(User u) { userDAO.delete(u); }
    public String getUser(int id) { userDAO.get(id); }
}

13. Access HttpServletRequest and HttpServletResponse

Simply declare the servlet objects as method parameters to obtain direct access:

@RequestMapping("/download")
public String doDownload(HttpServletRequest request, HttpServletResponse response) {
    // use request/response streams
    return "DownloadPage";
}

14. Follow the Single Responsibility Principle

Keep controllers thin by delegating business logic to service classes and create separate controllers for distinct domains (e.g., UserController, OrderController, PaymentController).

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaWeb DevelopmentannotationsControllerSpring MVCRequestMappingModelAndView
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.