package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Arrays; @Controller public class TestController { /** * 數組參數綁定 */ @RequestMapping("test") public void test(Integer[] ids) { System.out.println(Arrays.toString(ids)); /* [1, 2] */ } }
package com.zze.springmvc.pojo; import java.util.List; public class QueryVo { private List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } } package com.zze.springmvc.web.controller; import com.zze.springmvc.pojo.QueryVo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Arrays; @Controller public class TestController { /** * 集合參數綁定 */ @RequestMapping("test") public void test(QueryVo queryVo) { System.out.println(Arrays.toString(queryVo.getUsers().toArray())); /* [User{id=1, name='zhangsan'}, User{id=2, name='lisi'}] */ } }
若是要進行日期類型參數綁定,SpringMVC 默認是不支持的,須要咱們手動定義一個轉換器來告知 SpringMVC 如何轉換,以下:html
package com.zze.springmvc.web.converter; import org.springframework.core.convert.converter.Converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * String : 源類型 * Date : 目標類型 */ public class DateConverter implements Converter<String,Date> { public Date convert(String source) { Date date = null; try { date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } }
<!--自定義轉換器工廠--> <bean id="myConverters" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <!--註冊本身定義的日期轉換器--> <bean class="com.zze.springmvc.web.converter.DateConverter"/> </property> </bean> <!--使用上自定義的轉換器工廠--> <mvc:annotation-driven conversion-service="myConverters"/>
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { /** * 請求 /test1 和 /test2 都會指向 test 方法 */ @RequestMapping(value = {"test1", "test2"}) public void test() { } }
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("test") public class TestController { /** * 由於類上使用了 RequestMapping 註解,此時 test 方法的訪問路徑就爲: * /test/test1 和 /test/test2 */ @RequestMapping(value = {"test1", "test2"}) public void test() { } }
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class TestController { /** * 限定請求方法只能爲 GET 和 POST */ @RequestMapping(value = "test",method = {RequestMethod.POST,RequestMethod.GET}) public void test() { } }
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class TestController { /** * @RequestParam * name 指定所修飾參數對應請求參數名 * required 指定所修飾參數是否必須 * defaultValue 指定所修飾參數的默認值 */ @RequestMapping(value = "test") public void test(@RequestParam(name = "pid",required = false,defaultValue = "1") Integer id) { } }
在 SpringMVC 中,請求方法的返回值除了 ModelAndView,還能夠有以下幾種方式:java
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { /** * 轉發到 jsp */ @RequestMapping(value = "test") public String test() { // 由於配置了視圖解析器,這裏的 userlist 實際指向 /WEB-INF/jsp/userlist.jsp return "userlist"; } }
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { /** * 轉發到 Action */ @RequestMapping(value = "test") public String test() { return "forward:/user/list"; } }
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { /** * 重定向到 Action */ @RequestMapping(value = "test") public String test() { return "redirect:/user/list"; } }
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Controller public class TestController { /** * 訪問原生 request 和 response API */ @RequestMapping(value = "test") public void test(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain;charset=utf-8"); // request.getRequestDispatcher("/user/list").forward(request,response); 轉發 // response.sendRedirect("/user/list"); // 重定向 response.getWriter().write("你好世界"); } }
<filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>消息頁</title> </head> <body> ${msg} </body> </html>
package com.zze.springmvc.web.util; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyExceptionResolver implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("msg"); modelAndView.addObject("msg", "服務器異常!"); return modelAndView; } }
<!--註冊全局異常處理器--> <bean class="com.zze.springmvc.web.util.MyExceptionResolver"/>
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
<!-- 配置多媒體處理器 注意:這裏的 id 必須使用 multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--限制單次文件上傳大小不超過 8m--> <property name="maxUploadSize" value="8388608"/> </bean>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>圖片上傳</title> </head> <body> <form action="/fileupload" method="post" enctype="multipart/form-data"> <input type="file" name="picFile"> <input type="submit" value="上傳"> </form> </body> </html>
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; @Controller public class TestController { @RequestMapping(value = "fileupload", method = RequestMethod.GET) public String upload() { return "fileupload"; } @RequestMapping(value = "fileupload", method = RequestMethod.POST) public String upload(Model model, MultipartFile picFile) throws IOException { File file = new File("D:/upload/" + picFile.getOriginalFilename()); picFile.transferTo(file); model.addAttribute("msg", "上傳成功"); return "fileupload"; } }
// 新建目錄 D:/upload // 瀏覽器訪問 localhost:8080/fileupload
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.2</version>
package com.zze.springmvc.web.controller; import com.zze.springmvc.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.text.ParseException; import java.text.SimpleDateFormat; @Controller public class TestController { /** * 返回 JSON 格式數據 * 返回值設爲要序列化的類型,並在方法上添加上 @ResponseBody 註解 */ @RequestMapping("getUser") @ResponseBody public User getUser() throws ParseException { User user = new User(); user.setId(1); user.setName("張三"); user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1998-1-1")); user.setGender("男"); user.setAddress("河北"); return user; } }
package com.zze.springmvc.web.controller; import com.zze.springmvc.pojo.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class TestController { /** * 一、使用 @RequestBody 修飾入參 * 二、請求方式爲 POST,content-type 爲 application/json * 三、json 中字段名與 pojo 屬性一致 */ @RequestMapping("addUser") @ResponseBody public User addUser(@RequestBody User user){ System.out.println(user); user.setGender("女"); return user; } }
要使用該方式進行 JSON 交互,必須配置註解驅動。web
<!--配置註解驅動,至關於同時使用最新處理器映射器和處理器適配器,同時對 JSON 數據響應提供支持--> <mvc:annotation-driven/>
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class TestController { @RequestMapping("user/{id}") @ResponseBody public void getUser(@PathVariable Integer id){ System.out.println(id); /* 請求 localhost:8080/user/1 控制檯輸出: 1 */ } }
SpringMVC 的處理器攔截器相似於 Servlet 開發中的過濾器 Filter,用於對處理器進行預處理和後處理。spring
package com.zze.springmvc.web.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor1 implements HandlerInterceptor { /** * 處理器執行前執行 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor.preHandle"); return true; // true:放行 false:攔截 } /** * 處理器執行後, modelAndView 返回前執行 */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor.postHandle"); } /** * 處理器執行後執行 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor.afterCompletion"); } }
package com.zze.springmvc.web.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor2 implements HandlerInterceptor { /** * 處理器執行前執行 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor.preHandle"); return true; // true:放行 false:攔截 } /** * 處理器執行後, modelAndView 返回前執行 */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor.postHandle"); } /** * 處理器執行後執行 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor.afterCompletion"); } }
<!--註冊攔截器--> <mvc:interceptors> <mvc:interceptor> <!--攔截全部請求,包括二級以上目錄--> <mvc:mapping path="/**"/> <!--指定路徑不攔截--> <mvc:exclude-mapping path="/login"/> <bean class="com.zze.springmvc.web.interceptor.MyInterceptor1"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.zze.springmvc.web.interceptor.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { @RequestMapping("test") public void test() { System.out.println("from TestController.test"); } }