编写Spring MVC Controller

1、映射请求

在POJO类定义处标注@Controller,再通过<content:component-scan /...>扫描相应的类包,即可使POJO类成为一个能处理HTTP请求的控制器。
如何将请求映射到对应的控制器的方法中是Spring MVC框架最重要的任务之一,这项任务由@RequestMapping注释承担。
例子1:

 1 @Controller
 2 public class UserController{
 3
 4     @RequestMapping(value="/user/createUser")
 5     public String createUser(@ModelAttribute("user") User user){
 6         ...
 7         retrun "user/createSuccess";
 8     }
 9
10     @RequestMapping(value="/user/register")
11     public String register(@ModelAttribute("user") User user){
12         return "user/register";
13     }
14 }

@RequestMapping不但支持标准的URL,还支持Ant风格(即?、*和**字符)和带{xxx}占位符的URL,通过@PathVariable注释可以将URL中占位符参数映射到方法入参。
例子2:

 1 @Controller
 2 //将“/user”映射到Controller上
 3 @RequestMapping("/user")
 4 public class UserController{
 5
 6     @RequestMapping("/{userId}")
 7     public ModelAndView showDetial(@PathVariable("userId") String userId){
 8         ModelAndView mv = new ModelAndView();
 9         mv.setView("user/showDetail");
10         mv.addObject("user", userService.getUserById(userId));
11         return mv;
12     }
13
14 }

@RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法、请求头参数、请求参数(报文体和URL包含的请求参数)映射请求。
例子3:

 1 @Controller
 2 @RequestMapping("/user")
 3 public class UserController{
 4
 5     @RequestMapping(value="/delete", method = RequestMethod.POST, params = "userId")
 6     public String delete(@RequestParam("userId") String userId){
 7         ...
 8         return "user/list";
 9     }
10
11     @RequestMapping(value="/show", headers = "content-type=text/*")
12     public String show(@RequestParam("userId") String userId){
13         ...
14         return "user/show";
15     }
16 }

Spring MVC对控制器处理方法签名是很宽松的,用户可以按自己喜欢的方式进行方法签名,在必要时对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader等)
例子4:

 1 @RequestMapping("/param")
 2 public String handleParam(@RequestParam("userName") String userName,
 3                           @RequestParam("password") String password,
 4                           //如果不存在realName参数,也不抛出异常
 5                           @RequestParam(value = "realName", required = false) String realName ){
 6     return "success";
 7 }
 8
 9 @RequestMapping(value="/cookie")
10 //将Cookie值及报文头属性绑定到入参中
11 public ModelAndView handleCookie(@CookieValue("JESSIONID") String sessionId,
12                                  @RequestHeader("Accept-language" String acceptLanguage){
13     ModelAndView mv = new ModelAndView();
14     mv.setView("success");
15     mv.addObject("user", new User());
16     return mv;
17 }
18
19 @RequestMapping(value="/user")
20 //使用命令/表单对象绑定请求参数,请求参数按名称匹配的方式绑定到user的属性中、方法返回的字符串代表逻辑视图名
21 //如URL请求可以为:"/user.html?userName=tom&dept.deptId=1&dept.address.tel=102"
22 public String handleUser(User user){
23     return "success";
24 }
25
26 @RequestMapping(value="servlet1")
27 //使用ServletAPI对象作为入参,可组合使用
28 public void handleServlet1(HttpServletRequest request, HttpServletResponse response){
29     String userName = WebUtils.findParameterValue(request, "userName");
30     response.addCookie(new Cookie("userName", userName));
31 }
32
33 @RequestMapping(value="servlet2")
34 public String handleServlet2(HttpSession session){
35     session.setAttribute("sessionId", 1234);
36     return "success";
37 }

2、处理模型数据

将模型数据输出给视图是Spring MVC框架的一项重要工作,有以下几种途径输出模型数据:

 1 @RequestMapping("/user/showDetail")
 2 //使用ModelAndView返回值,指定一个具体的视图对象和一个逻辑图名
 3 public ModelAndView showDetial(@PathVariable("userId") String userId){
 4     ModelAndView mv = new ModelAndView();
 5     mv.setView("user/showDetail");
 6     mv.addObject("user", userService.getUserById(userId));
 7     return mv;
 8 }
 9
10 @RequestMapping(value="/model1")
11 //在方法入参处使用@ModelAttribute,入参对象就回放到数据模型中,视图createSuccess.jsp就可以通过${user.userName}等方式访问模型中的数据。
12 public String handleModel1(@ModelAttribute("user") User user){
13     user.setUserId("1000");
14     return "user/createSuccess";
15 }
16
17 @RequestMapping(value="/model3")
18 //入参为Map、Model、ModelMap时,处理方法返回时,数据自动添加到模型中
19 public String handleModel3(ModelMap modelMap){
20     modelMap.AddAttribute("testAttr", "value1");
21     User user = (User)modelMap.get("user");
22     user.setUserName("tom");
23     return "/user/showUser";
24 }

@SessionAttribute这个注解只有当你想在某个特定的事件处理中临时保存session会话(红色标注)的时候才适用,而当需要永久保存session的话,还是采用常规的方法,比如说:session.setAttribute,使用@SessionAttribute 的例子:

 1 @Controller
 2 @RequestMapping("/user")
 3 @SessionAttributes("user")
 4 public class UserController{
 5
 6     //由于@SessionAttribute的处理机制,把对象存入Session时,Session中必须已经有对应属性,没有即报错
 7     @ModelAttribute("user")
 8     public User getUser(){
 9         User user = new User();
10         user.setUserId("1001");
11         return user;
12     }
13
14     @RequestMapping(value="/model4")
15     public String handleModel4(@ModelAttribute("user") User user){
16         user.setUserName("John");
17         //发起一个请求,由handleModel5处理
18         return "redirect:/user/model5.html";
19     }
20     @RequestMapping("/model5")
21     public String handleModel5(ModelMap modelMap, SessionStatus sessionStatus){
22         //获取HttpSession中名为“user”的模型属性
23         User user = (User)modelMap.get("user");
24
25     }
26 }

3、数据校验

具体配置和使用,见:Spring Validation(使用Hibernate Validator。使用@Valid的例子:

 1 @Controller
 2 @RequestMapping("/user")
 3 public class UserController{
 4     ...
 5     @RequestMapping(value="/valid1")
 6     //在入参对象前添加@Valid注解,同时声明一个BindingResult的入参
 7     public String handleValid1(@Valid @ModelAttribute("user") User user, BindingResult bindingResult){
 8         if(bindingResult.hasErrors()){
 9             return "user/register3";
10         }else{
11             return "user/showUser";
12         }
13     }
14 }

4、文件上传

JSP例子:

 1 <html>
 2     <head>
 3         <title>Upload a file please</title>
 4     </head>
 5     <body>
 6         <h1>Please upload a file</h1>
 7         <form method="post"action="/form"enctype="multipart/form-data">
 8             <input type="text"name="name"/>
 9             <input type="file"name="file"/>
10             <input type="submit"/>
11         </form>
12     </body>
13 </html>

Controller的写法:

 1 @RequestMapping(method=RequestMethod.POST)
 2 public String addSpitterFromForm(@Valid Spitter spitter, BindingResult bindingResult,
 3                                  //使用MultipartFile类型入参,接收文件上传
 4                                  @RequestParam(value="image", required=false) MultipartFile image){
 5     if(bindingResult.hasErrors()){
 6         return "spitters/edit";
 7     }
 8
 9     spitterService.saveSpitter(spitter);
10
11     try{
12         if(!image.isEmpty()){
13             validateImage(image);
14             saveImage(spitter.getId() + ".jpg", image);
15         }
16     }
17     catch(ImageUploadException e){
18         bindingResult.reject(e.getMessage());
19         return "spitters/edit";
20     }
21
22     return "redirect:/spitters/" + spitter.getUserName();
23 }
24
25 //校验图片
26 private void validateImage(MultipartFile image) throws ImageUploadException{
27     if(!image.getContentType().equals("image/jpeg")){
28         throw new ImageUploadException("Only JPG images accepted");
29     }
30 }
31
32 //保存文件
33 private void saveImage(String filename, MultipartFile image) throws ImageUploadException{
34     try{
35         File file = new File(webRootPath + "resources/" + filename);
36                 fileUtils.writeByteArrayToFile(file, image.getBytes());
37     }
38     catch(IOException e){
39         throw new ImageUploadException("Unable to save image", e);
40     }
41 }

使用Servlet3.0时也可以使用javax.servlet.http.Part:

1 @Controller
2 public class FileUploadController {
3     @RequestMapping(value = “/form”, method = RequestMethod.POST)
4     public String handleFormUpload(@RequestParam(“name”) String name,
5                                    @RequestParam(“file”) Part file) {
6         InputStream inputStream = file.getInputStream();
7         // store bytes from uploaded file somewhere
8         return “redirect:uploadSuccess”; }
9 }

5、参考

《Spring3.0就这么简单》

时间: 2024-12-21 10:02:00

编写Spring MVC Controller的相关文章

Posting JSON to Spring MVC Controller

Spring MVC can be setup to automatically bind incoming JSON string into a Java object. Firstly, ensure you have jackson-mapper-asl included on the classpath: <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-

Spring MVC Controller单例陷阱

Spring MVC Controller默认是单例的: 单例的原因有二: 1.为了性能. 2.不需要多例. 1.这个不用废话了,单例不用每次都new,当然快了. 2.不需要实例会让很多人迷惑,因为spring mvc官方也没明确说不可以多例. 我这里说不需要的原因是看开发者怎么用了,如果你给controller中定义很多的属性,那么单例肯定会出现竞争访问了. 因此,只要controller中不定义属性,那么单例完全是安全的.下面给个例子说明下: package com.lavasoft.dem

Spring MVC Controller与jquery ajax请求处理json

在用 spring mvc 写应用的时候发现jquery传递的[json数组对象]参数后台接收不到,多订单的处理,ajax请求: var cmd = {orders:[{"storeId":"0a1", "address":"西斗门路2号", "goods":[{"goodsId":"1"}, {"goodsId":"2"},

spring mvc controller中获取request head内容

spring mvc controller中获取request head内容: @RequestMapping("/{mlid}/{ptn}/{name}") public String print(@PathVariable Integer mlid, @PathVariable String ptn, @PathVariable String name, HttpSession session, Model model, @RequestHeader String referer,

转:【Spring MVC Controller单例陷阱】

http://lavasoft.blog.51cto.com/62575/1394669/ Spring MVC Controller默认是单例的: 单例的原因有二:1.为了性能.2.不需要多例. 1.这个不用废话了,单例不用每次都new,当然快了.2.不需要实例会让很多人迷惑,因为spring mvc官方也没明确说不可以多例. 我这里说不需要的原因是看开发者怎么用了,如果你给controller中定义很多的属性,那么单例肯定会出现竞争访问了. 因此,只要controller中不定义属性,那么单

Spring MVC Controller中解析GET方式的中文参数会乱码的问题

Spring MVC Controller中解析GET方式的中文参数会乱码的问题 问题描述 在工作上使用Spring老是碰到一个问题,使用Controller处理GET方式的请求参数时,服务端得到的结果会碰到乱码,之前翻阅了很多与Java EE相关的很多乱码处理资料,不管是加过滤器还是统一文件编码,都没能正确解决,后来设计接口时,一直采用先Base64,然后再作为参数传过来的方式解决的.最近找到了根本的解决方案,顺手记下来. 为何会乱码 Spring MVC 是基于Servlet,在Http请求

Spring MVC Controller 单元测试

简介 Controller层的单元测试可以使得应用的可靠性得到提升,虽然这使得开发的时间有所增加,有得必失,这里我认为得到的比失去的多很多. Sping MVC3.2版本之后的单元测试方法有所变化,随着功能的提升,单元测试更加的简单高效. 这里以4.1版本为例,记录Controller的单元测试流程.非常值得参考的是Spring MVC Showcase(https://github.com/spring-projects/spring-mvc-showcase),它当前的版本使用的是4.1.0

Spring MVC Controller中解析GET方式的中文参数会乱码的问题(tomcat如何解码)

Spring MVC Controller中解析GET方式的中文参数会乱码的问题 问题描述 在工作上使用突然出现从get获取中文参数乱码(新装机器,tomcat重新下载和配置),查了半天终于找到解决办法. 为何会乱码 Spring MVC 是基于Servlet,在Http请求到达Servlet解析之前,GET过来的URL已经被Tomcat先做了一次URLDecode.Tomcat对GET方式默认的URL解码结果是iso-8859-1而不是我认为的UTF-8. 解决方案 解决方案也很简单,除了平常

spring mvc Controller与jquery Form表单提交代码demo

1.JSP表单 <% String basePath = request.getScheme() + "://" + request.getServerName() +":"+ request.getServerPort() + request.getContextPath() + "/"; %> <script language="javascript" type="text/javascript