完整的项目案例: springmvc.zip
目录
实例
项目结构路径:
一、配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置请求总控器 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
二、配置dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mcv="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 启用注解并扫描 --> <context:component-scan base-package="edu.nf.ch04.controller"/> <!-- 启用mvc注解驱动,这个注解同时还注册了Springmvc内置的多种HttpMessageConverter(消息转换器), 它主要用于将Http请求报文的字符串信息转换成用@ReqeustBody注解修饰的方法参数对象, 同时基于@ResponseBody修饰的返回值进行数据转换然后响应客户端。如果请求处理方法的参数和方法的返回值 没有使用@RequestBody和ResponseBody,那么spring将使用额外的Converter SPI来完成请求方法参数的类型转换--> <!-- 可以指定conversion-service来自定义Converter转换器。 注意:自定义Converter和自定义HttpMessageConverter是两种不同的转换器, 自定义Converter是实现Converter接口,而自定义HttpMessageConverter是 实现HttpMessageConverter接口,如果需要自定义HttpMessageConverter可以在 <mvc:annotation-driven>中加入配置<mvc:message-converters>--> <mvc:annotation-driven conversion-service="conversionService"> <!-- 自定义一个消息转换器,register-defaults设置为true 则同时注册默认的HttpMessageConverter和自定义的HttpMessageConverter, 设置为false则只会注册自定义的HttpMessageConverter--> <!--<mvc:message-converters register-defaults="true"> <ref bean="myMessageConverter"/> </mvc:message-converters>--> </mvc:annotation-driven> <!-- 指定Converter转换器, 配置ConversionServiceFactoryBean来注册一个自定义Converter --> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <bean class="edu.nf.ch04.converter.MyConverter"/> </property> </bean> <!-- 处理静态资源--> <mcv:default-servlet-handler/> <!-- 配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
三、数据绑定controller(DemoController)
package edu.nf.ch04.controller; import edu.nf.ch04.entity.Address; import edu.nf.ch04.entity.Users; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.format.datetime.DateFormatter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.text.SimpleDateFormat; import java.util.Date; /** * @author wangl * @date 2018/10/29 */ @Controller public class DemoController { /** * 默认参数名对应<input name="名称"/>, * 如果名称不一致时,可以使用@RequestParam注解进行绑定 * 而注解的value对应<input name="名称"/> * @param userName * @param age * @return */ @PostMapping("/add") public ModelAndView add(@RequestParam("userName") String userName, @RequestParam("age") Integer age){ System.out.println(userName); System.out.println(age); return new ModelAndView("index"); } /** * 也可以映射成一个Bean对象,而对象的字段名对应<input name="名称"/> * ,也可以将要映射的集合对象定义在实体对象中,同样可以完成集合类型的映射 * (注意:不能单独在controller的方法参数中声明List等集合类型,spring是不会自动映射的 * @param user * @return */ @PostMapping("/add2") public ModelAndView add2(Users user){ System.out.println(user.getUserName()); System.out.println(user.getAge()); for (Address address : user.getAddress()) { System.out.println(address.getAddr()); } return new ModelAndView("index"); } /** * 通过请求url地址映射参数 * 使用@PathVariable注解映射url地址中的变量名, * value属性值对应{userId} * @param uid * @return */ @GetMapping("/user/{userId}") public ModelAndView getUser(@PathVariable("userId") Integer uid){ ModelAndView mv = new ModelAndView("userinfo"); if(uid == 1001){ Users user = new Users(); user.setUserName("user1"); user.setAge(21); //类似于放入请求作用域 mv.addObject("user", user); } return mv; } /** * 方式一: * 日期转换方法,@InitBinder标注的方法会在执行controller方法之前先执行 * ,并且需要传入一个WebDataBinder参数,这个参数用于注册日期类型转换器 * @param binder * @return */ @InitBinder public void convert(WebDataBinder binder){ binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd")); } /** * 日期类型的转换处理,先会执行上面@InitBinder标注的方法注册一个日期转换器, * 再调用当前的controller方法将转换的值赋值到user实体中的birth字段 * @param user * @return */ @PostMapping("/add3") public ModelAndView convertDate(Users user){ System.out.println(user.getBirth()); return new ModelAndView("index"); } /** * 传入ServletAPI的原生对象 * @param request * @param session * @return */ @GetMapping("/api") public ModelAndView servletApi(HttpServletRequest request, HttpSession session){ System.out.println(request); System.out.println(session); return new ModelAndView("index"); } }
前端请求页面:(adduser.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="add3"> Username:<input type="text" name="userName"/><br/> Age:<input type="text" name="age"/><br/> Birth:<input type="text" name="birth"><br/> <!-- 映射集合类型(普通类型) --> <!--Addr1:<input type="text" name="address"/><br/> Addr2:<input type="text" name="address"/><br/>--> <!-- 映射集合(实体对象)--> Addr1:<input type="text" name="address[0].addr"/><br/> Addr2:<input type="text" name="address[1].addr"/><br/> <input type="submit" value="add"/> </form> </body> </html>
前端请求页面:(getuser.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="user/1001">获取用户信息</a> </body> </html>
四、自定义类型转换 (ConverterController)
package edu.nf.ch04.controller; import edu.nf.ch04.entity.People; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.ModelAndView; /** * @author wangl * @date 2018/10/31 */ @Controller public class ConverterController { /** * 自定义类型转换 * @param people * @return */ @PostMapping("/convert") public ModelAndView convert(People people){ System.out.println(people.getName()); System.out.println(people.getAge()); return new ModelAndView("index"); } }
自定义类型转换器:
package edu.nf.ch04.converter; import edu.nf.ch04.entity.People; import org.springframework.core.convert.converter.Converter; /** * @author wangl * @date 2018/10/31 * 自定义类型转换器,需要实现Converter接口, * 这个转换器将name-age格式的字符串转换成People对象 */ public class MyConverter implements Converter<String, People> { @Override public People convert(String s) { People p = new People(); if(s != null && !"".equals(s)){ String[] array = s.split("-"); if(array.length == 2){ p.setName(array[0]); p.setAge(Integer.valueOf(array[1])); } } return p; } }
前台页面(converter.html):
实体类:
Address:
package edu.nf.ch04.entity; /** * @author wangl * @date 2018/10/29 */ public class Address { private String addr; public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } }
People:
package edu.nf.ch04.entity; /** * @author wangl * @date 2018/10/31 */ public class People { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
Users:
package edu.nf.ch04.entity; import org.springframework.format.annotation.DateTimeFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author wangl * @date 2018/10/29 */ public class Users { private String userName; private Integer age; /** * 方式二: * 在实体中使用@DateTimeFormat完成日期的类型转换 */ //@DateTimeFormat(pattern = "yyyy-MM-dd") private Date birth; /** * 映射集合(集合中是普通的类型,如String) */ //private List<String> address = new ArrayList<>(); /** * 映射集合(集合中是实体对象类型) */ private List<Address> address = new ArrayList<>(); public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } /*public List<String> getAddress() { return address; } public void setAddress(List<String> address) { this.address = address; }*/ public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public List<Address> getAddress() { return address; } public void setAddress(List<Address> address) { this.address = address; } }