参考资料:https://spring-mvc.linesh.tw/
1. 请求参数映射
GET 请求参数拼接在 URL 路径上,eg:
POST 请求参数 在 请求消息体中,eg:Form Data 或 Request payload
1.1 @RequestMapping
@RequestMapping
注解 作用:是建立请求 URL 和处理方法之间数据的对应关系。 该注解可以作用在方法和类上:
注意:/ 表示应用的根目录开始,路径上不能只写一个 /
属性:
path : 指定请求路径的 urlvalue : value 属性和 path 属性是一样的method : 指定该方法的请求方式params : 指定限制请求参数的条件headers : 发送的请求中必须包含的请求头
1 2 3 4 5 6 7 8 9 10 11 @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/login") public String login () { System.out.println("login..." ); return "/success.jsp" ; } }
1.2 @RequestParam
@RequestParam
注解 作用:把请求中的指定名称的参数传递给控制器中的形参赋值
value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供
映射机制 : 表单提交的数据都是 k=v 格式的,如 username=jack&password=123 SpringMVC 的参数映射过程是把表单提交的请求参数,作为控制器中方法的参数进行映射的
映射要求 :
提交表单的 name属性 和 形参的名称 必须相同
,否则获取到的为 null。
支持类型 :
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)
日期类型转换处理(Date)
1.2.1 基本类型映射 提交表单的name和参数的名称必须相同
的,区分大小写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class UserController { @RequestMapping("/test_param") public void test_param (String id) { System.out.println("id=" + id); } @RequestMapping("/test_param2") public void test_param2 (@RequestParam("id") String uid, String name) { System.out.println("uid=" + uid + ", name=" + name); } }
1.2.2 实体类映射 要求提交表单的 name 和 JavaBean 中的属性名称需要一致,如果一个 JavaBean 类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性
↓ demo 例子如下 - 同集合映射 demo ↓
1.2.3 集合映射
list[index].属性名
map['key'].属性名
注意:如果请求参数是中文,可以在 web.xml 中配置 Spring 提供的字符集过滤器来解决中文乱码问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String username; private String password; private List<Car> carList; private Map<String, Car> carMap; private Date birth; }public class UserController { @RequestMapping("/test_entity") public void test_entity (User user) { System.out.println(user); } }
1.2.4 Demo配置文件 web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app > <display-name > Archetype Created Web Application</display-name > <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 > </filter > <filter-mapping > <filter-name > characterEncodingFilter</filter-name > <url-pattern > /*</url-pattern > </filter-mapping > <servlet > <servlet-name > dispatcherServlet</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:springmvc.xml</param-value > </init-param > <load-on-startup > 1</load-on-startup > </servlet > <servlet-mapping > <servlet-name > dispatcherServlet</servlet-name > <url-pattern > /</url-pattern > </servlet-mapping > </web-app >
springmvc.xml
1 2 3 4 5 6 7 8 9 10 <context:component-scan base-package ="com.demo" /> <bean id ="internalResourceViewResolver" class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp" /> </bean > <mvc:annotation-driven />
1.2.5 Date类型映射 如果对象的属性中有Date类型,页面输入参数格式是 2019/1/1 可以自动参数映射,如果页面输入参数格式是 2019-1-1 则无法映射,需要使用自定义类型转换器来解决。
↑ demo 例子如上 - 同集合映射 demo ↑
注意:表单提交的任何数据类型全部都是字符串类型,但是后台定义 Integer 类型,数据也可以封装上,说明 Spring 框架内部会默认进行数据类型转换。
如果想自定义数据类型转换,可以实现 Converter 的接口
。
创建日期转换工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class StringToDateConverter implements Converter <String, Date> { @Override public Date convert (String s) { if ("" .equals(s)) { throw new RuntimeException ("日期字符串不能为空" ); } try { return new SimpleDateFormat ("yyyy-MM-dd" ).parse(s); } catch (ParseException e) { e.printStackTrace(); } throw new RuntimeException ("日期类型转换异常" ); } }
修改 springmvc.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <context:component-scan base-package ="com.demo" /> <bean id ="internalResourceViewResolver" class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp" /> </bean > <bean id ="conversionServiceFactoryBean" class ="org.springframework.context.support.ConversionServiceFactoryBean" > <property name ="converters" > <set > <bean class ="com.demo.utils.StringToDateConverter" /> </set > </property > </bean > <mvc:annotation-driven conversion-service ="conversionServiceFactoryBean" />
1.3 @PathVariable
@PathVariable
注解 - Restful 作用:拥有映射 url 中的占位符的。url 中有 /delete/{id} ,{id} 就是占位符,也叫 URI模板
1 2 3 4 5 6 7 8 public class UserController { @RequestMapping(value="/testPathVariable/{id}") public String testPathVariable (@PathVariable("id") String uid) { System.out.println(uid); return "success" ; } }
此之谓:Restful 风格的 URL
,即通过 @PathVariable 实现: 请求路径一样,可以根据不同的请求方式去执行后台的不同方法,如京东的商品链接… restful风格的URL优点:结构清晰、符合标准、易于理解、扩展方便
@RequestHeader
注解 作用:获取指定请求头的值
1 2 3 4 5 6 7 8 public class UserController { @RequestMapping(value="/testRequestHeader") public String testRequestHeader (@RequestHeader(value="Accept") String header) { System.out.println(header); return "success" ; } }
1.5 @CookieValue
@CookieValue
注解 作用:用于获取指定cookie的名称的值
1 2 3 4 5 6 7 8 public class UserController { @RequestMapping(value="/testCookieValue") public String testCookieValue (@CookieValue(value="JSESSIONID") String cookieValue) { System.out.println(cookieValue); return "success" ; } }
1.6 @RequestPart
@RequestPart
注解 作用:用于 multipart/form-data 表单提交请求的方法上,主要是文件上传。支持请求方法的方式 MultipartFile,属于Spring的MultipartResolver类,该请求通过http协议传输的。
1 2 3 4 5 6 7 8 9 public class UserController { @RequestMapping("uploadFile") public String uploadFile (@RequestPart("file") MultipartFile file, @RequestParam String bucket) { String fileUrl = aliossService.uploadFile(file, bucket); Map<String, String> result = new HashMap <>(); result.put("fileUrl" , fileUrl); return "success" ; } }
2. 响应数据和结果视图 2.1 返回值分类
String (String 返回值 + Model 参数
) Controller 方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。 应用时可以设置参数类型为 Model,使用 Model 对象调用 addAttribute 方法来存储数据,同 request。
request.setAttribute(“data”, data);
model.addAttribute(“data”, data);
void (void 返回值 + request/response跳转
) 如果控制器的方法返回值编写成 void,执行程序报 404 的异常,默认查找 JSP 页面没有找到。 应用时可以设置参数类型为 HttpServletRequest 和 HttpServletResponse,使用转发或者重定向来跳转页面
ModelAndView (.addObject()存储数据
+ .setViewName()跳转
) ModelAndView 对象是 Spring 提供的一个对象,可以调用 addObject 方法来保存数据以及调用 setViewName 方法来跳转页面。
forward: 和 redirect: (不会拼接配置的视图解析器中的前缀和后缀到路径里
) 可以在前端控制器的方法中直接返回 forward: 或 redirect: 为前缀的路径字符串,由 SpringMVC 反射中自动解析路径选择 转发或重定向 跳转页面。
使用forward关键字进行请求转发:return “forward:转发的JSP路径”
使用redirect关键字进行重定向(默认会把项目路径加上
):return “redirect:重定向的JSP路径”
User
1 2 3 4 5 6 7 8 @Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String username; private String password; }
UserController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 @Controller @RequestMapping("/user") public class UserController { public List<User> getUsers () { List<User> list = new ArrayList <User>(); list.add(new User (1 , "aaa" , "123" )); list.add(new User (2 , "bbb" , "456" )); list.add(new User (3 , "ccc" , "789" )); return list; } @RequestMapping("/testString") public String testString (HttpServletRequest request) { List<User> users = getUsers(); request.setAttribute("users" , users); return "/list.jsp" ; } @RequestMapping("/testVoid") public void testVoid (HttpServletRequest request, HttpServletResponse response) throws Exception { List<User> users = getUsers(); request.setAttribute("users" , users); request.getRequestDispatcher("/WEB-INF/jsp/list.jsp" ).forward(request, response); } @RequestMapping("/testModelAndView") public ModelAndView testModelAndView () { List<User> users = getUsers(); ModelAndView modelAndView = new ModelAndView (); modelAndView.addObject("users" , users); modelAndView.setViewName("/list.jsp" ); return modelAndView; } @RequestMapping("testForwardAndRedirect") public String testForwardAndRedirect (HttpServletRequest request) { List<User> users = getUsers(); request.getSession().setAttribute("users" , users); return "forward:/index.jsp" ; } }
web.xml:中文乱码过滤器、前端控制器。
springmvc.xml
1 2 3 4 5 6 7 8 9 10 <context:component-scan base-package ="com.demo" /> <bean id ="internalResourceViewResolver" class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp" /> </bean > <mvc:annotation-driven />
3. 配置不拦截静态资源 DispatcherServlet 会拦截到所有的资源,导致一个问题就是静态资源 img、css、js 也会被拦截到,从而不能被使用。
解决方案就是需要配置静态资源不进行拦截,在 springmvc.xml 配置文件添加如下配置:
方式一:<mvc:resources>
+ <servlet-mapping>
1 2 3 4 5 6 7 8 9 10 <mvc:resources location ="/css/" mapping ="/css/**" /> <mvc:resources location ="/images/" mapping ="/images/**" /> <mvc:resources location ="/js/" mapping ="/js/**" /> <servlet-mapping > <serlvet-name > default</serlvet-name > <url-pattern > *.html</url-pattern > </servlet-mapping >
方式二:所有静态资源不被拦截
1 2 <mvc:default-servlet-handler />