今天看到一篇讲解 Spring MVC Controller 的文章,比较详细,顺道翻译下。
在 Spring MVC 中,我们写一个 Controller 类来处理客户端的请求。在 Controller 中处理相关的业务流程与业务逻辑并且通过 Spring 的 dispatcher servlet 返回对应的结果输出。这就是一个典型的 request response 周期。 ##1.使用 @Controller 注解
创建一个 Controller 类。在这个 Controller 来处理多个不同的提交.示例: import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping("/")
public String visitHome() {
// do something before returning view name
return "home";
}
}
当应用访问路径为根目录(/)时 进入这个方法
注意: 在Spring的配置文件中加入如下配置:
<annotation-driven />
也可以设置上 Controller 的扫描路径
<context:component-scan base-package="net.codejava.spring" />
使用 @Controller 注解,你可以提交多个表单到这个类中处理这些不同请求:
@Controller
public class MultiActionController {
@RequestMapping("/listUsers")
public ModelAndView listUsers() {
}
@RequestMapping("/saveUser")
public ModelAndView saveUser(User user) {
}
@RequestMapping("/deleteUser")
public ModelAndView deleteUser(User user) {
}
}
你的提交路径可以为 /listUsers, /saveUser 和 /deleteUser
##2.实现 Controller 接口
另一个创建 Controller 的方法就是实现 Controller 接口,示例:
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");
}
}
实现这个接口必须重写 handleRequest() 这个方法。这样才能被 spring 的 dispatcher servlet 捕获。当一个方法进来,request 的 Url 需要匹配如下的 Spring 配置:
<bean name="/main" class="net.codejava.spring.MainController" />
这种方法的缺点就是无法处理多个不同的提交请求。
##3.Extending the AbstractController Class
可以简单的处理 Http 请求方法类型(GET/POST),管理页面的缓存设置,即是否允许浏览器缓存当前页面;管理执行流程在会话(Session)上的同步。实例: 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");
}
}
Spring 中的配置:
<bean name="/big" class="net.codejava.spring.BigController">
<property name="supportedMethods" value="POST"/>
</bean>
##4. 通过 URL 映射处理提交。
这个就是我们经常用到的了。
@RequestMapping("/login")
当请求Url 匹配以上的路径 login 就会进入到这个 Controller 中。示例:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
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";
}
}
@RequestMapping 这个注解也可以设置多个相同的操作的url 提交到同一个方法中 ,示例:
@RequestMapping({"/hello", "/hi", "/greetings"})
##5 指定http请求方式
通过 @RequestMapping 注解的参数,指定方法处理指定的http请求。
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";
}
}
可以看到,以上的url相同,指定的提交方式不同,会通过提交方式进入不同的方法。
##6.请求参数的映射处理:
可以通过 @RequestParam 来接收表单参数提交并处理示例:
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String doLogin(@RequestParam String username,
@RequestParam String password) {
}
会 binds 提交的 username 以及 password 参数。get的url 会是这个样子:
http://localhost:8080/spring/login?username=scott&password=tiger
下面是几个常见数据处理示例:
@RequestParam int securityNumber//自动转化为int型
@RequestParam("SSN") int securityNumber//提交的参数与定义不同
@RequestParam(required = false) String country//非必须的接收参数
@RequestParam(defaultValue = "18") int age//设置参数默认值
doLogin(@RequestParam Map<String, String> params)//将提交所有信息放如map中
//使用HttpServletRequest 和 HttpServletResponse
@RequestMapping("/download")
public String doDownloadFile(
HttpServletRequest request, HttpServletResponse response) {
// access the request
// access the response
return "DownloadPage";
}
##7.返回 Model 以及 View
将数据处理封装之后返回视图层。
//返回登录页面:loginForm
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String viewLogin() {
return "LoginForm";
}
//封装数据返回视图层
@RequestMapping("/listUsers")
public ModelAndView listUsers() {
List<User> listUser = new ArrayList<>();
// get user list from DAO...
ModelAndView modelView = new ModelAndView("UserList");
modelView.addObject("listUser", listUser);
return modelView;
}
//将数据装入model 返回视图层
@RequestMapping(method = RequestMethod.GET)
public String viewStats(Map<String, Object> model) {
model.put("siteName", "CodeJava.net");
model.put("pageviews", 320000);
return "Stats";
}
//重定向到一个页面
// check login status....
if (!isLogin) {
return new ModelAndView("redirect:/login");
}
// return a list of Users
##8.验证表单提交。 Spring 可以简单的绑定数据到 一个 bean 中并经行校验。示例:
@Controller
public class RegistrationController {
@RequestMapping(value = "/doRegister", method = RequestMethod.POST)
public String doRegister(
@ModelAttribute("userForm") User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
// form validation error
} else {
// form input is OK
}
// process registration...
return "Success";
}
}
这里给出一篇问下 详细说明了 BindingResult 的处理 Spring MVC Form Validation Example with Bean Validation API
##9.处理上传表单: Spring 使用 Apache Commons FileUpload 作为上传的处理。示例:
@RequestMapping(value = "/uploadFiles", method = RequestMethod.POST)
public String handleFileUpload(
@RequestParam CommonsMultipartFile[] fileUpload) throws Exception {
for (CommonsMultipartFile aFile : fileUpload){
// stores the uploaded file
aFile.transferTo(new File(aFile.getOriginalFilename()));
}
return "Success";
}