14 Must-Know Spring MVC Controller Tips for Better Backend Development

This article walks through fourteen practical techniques for building Spring MVC controllers, covering annotation‑based definitions, interface implementation, extending abstract classes, URL mapping, request method handling, parameter binding, model handling, redirects, form validation, file uploads, autowiring services, and best practices such as single‑responsibility and domain‑specific controller design.

Java Backend Technology
Java Backend Technology
Java Backend Technology
14 Must-Know Spring MVC Controller Tips for Better Backend Development

In Spring MVC a controller class handles client requests, delegates business logic, and returns a logical view name for the DispatcherServlet to render, completing the typical request‑response cycle. The following fourteen tips help you write clean, maintainable controllers.

1. Use @Controller Annotation

Annotate a class with @Controller to make it a Spring MVC controller capable of handling one or more requests.

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

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

Ensure annotation‑driven scanning is enabled in the Spring configuration (e.g., <annotation-driven /> and appropriate

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

).

2. Implement the Controller Interface

Alternatively, a controller can implement the org.springframework.web.servlet.mvc.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");
    }
}

Map the bean name to a URL in the Spring XML configuration (e.g.,

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

). This approach handles a single URL only.

3. Extend AbstractController

For finer control over supported HTTP methods, session handling, and caching, extend AbstractController.

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

Configure supported methods in the bean definition, e.g., <property name="supportedMethods" value="POST" />.

4. Map URLs with @RequestMapping

Use @RequestMapping to bind a URL pattern to a controller class or method.

@RequestMapping("/login")

When placed on a class, it creates a single‑action controller; on a method, it enables multi‑action controllers.

5. Specify HTTP Methods

Define the HTTP verb a handler supports via the method attribute of @RequestMapping.

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

6. Bind Request Parameters with @RequestParam

Retrieve query or form parameters directly as method arguments.

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

Attributes such as required and defaultValue control optionality and fallback values.

7. Return ModelAndView

Return a ModelAndView to specify both view name and model data.

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

Alternatively, accept a ModelAndView parameter and modify it.

8. Add Objects to the Model

Use addObject or a Map<String,Object> to place data into the model.

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

9. Perform Redirects

Return a view name prefixed with redirect:/ to issue a client redirect.

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

10. Handle Form Submission and Validation

Bind form fields to a command object with @ModelAttribute and validate using BindingResult.

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

11. Process File Uploads

Accept an array of CommonsMultipartFile and store each file.

@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. Autowire Business Services

Inject service or DAO beans into the controller with @Autowired.

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

    public String listUser() {
        userDAO.list();
        return "UserList";
    }
    // other CRUD methods delegating to userDAO
}

13. Access HttpServletRequest/HttpServletResponse Directly

Add the servlet request or response as method parameters when low‑level access is needed.

@RequestMapping("/download")
public String doDownloadFile(HttpServletRequest request, HttpServletResponse response) {
    // read/write streams, set headers, etc.
    return "DownloadPage";
}

14. Follow the Single‑Responsibility Principle

Keep controllers thin by delegating business logic to separate service/DAO classes and create domain‑specific controllers (e.g., UserController, OrderController, PaymentController).

Applying these fourteen tips will help you design Spring MVC controllers that are clean, modular, and easy to maintain.

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.

JavaspringControllerSpring MVC
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.