Spring MVC框架是一个开源的Java平台,为开发强大的基于Java的Web应用程序提供全面的基础架 构支持非常容易和非常快速。 Spring框架最初由Rod Johnson撰写,并于2003年6月根据Apache 2.0许可证首次发布。 Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用 程序的组件。 MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元 素之间的松散耦合。 模型(Model)封装了应用程序数据,通常它们将由POJO类组成。 视图(View)负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出。(jsp、 freemarker、thymeleaf for html5) 控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。 Spring MVC 是一个模型 - 视图 - 控制器(MVC)的Web框架建立在中央前端控制器servlet (DispatcherServlet),它负责发送每个请求到合适的处理程序,使用视图来最终返回响应结果的概 念。Spring MVC 是 Spring 产品组合的一部分,它享有 Spring IoC容器紧密结合Spring松耦合等特点, 因此它有Spring的所有优点。
接下来开始使用
先添加依赖
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.17</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2</version>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.2</version>
接下来进行配置 全注解配置
编写AppConfig控制类
在这个类里需要配置编码过滤器 跨域处理 静态资源访问(不配置无法访问静态资源)
视图处理器 json数据处理 以及java8的日期处理
//标注为配置类
@Configuration
//启用springmvc
@EnableWebMvc
@Controller
@ComponentScan("cn.chenxiejia")
public class AppConfig implements WebApplicationInitializer, WebMvcConfigurer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
//相当于spring中的
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载配置类 本类
ctx.register(this.getClass());
ctx.setServletContext(servletContext);
//配置dispatcher servletContext代表整个web应用,可以和程序的容器(服务器)来通信
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
//值大于0会在项目开始时就加载并初始化 小于0会在使用这个servlet时才加载 数值越小优先级越高
servlet.setLoadOnStartup(1);
//使用spring默认的编码过滤器
var fc = new CharacterEncodingFilter("utf-8");
FilterRegistration.Dynamic ff = servletContext.addFilter("fc", fc);
//解决out输出乱码
ff.setInitParameter("forceEncoding", "true");
ff.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), true, "/*");
}
//跨域处理
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*.*")
.allowedOrigins("*")
.allowedMethods("get", "post")
.allowCredentials(false)
.maxAge(3600);
}
//静态资源访问
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/imgs/**").addResourceLocations("/imgs/");
registry.addResourceHandler("/i.html").addResourceLocations("/i.html");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//配置编码方式
Charset cs = StandardCharsets.UTF_8;
StringHttpMessageConverter shmc = new StringHttpMessageConverter();
shmc.setDefaultCharset(cs);
var list = List.of(MediaType.parseMediaType("text/html;charset=UTF-8"));
shmc.setSupportedMediaTypes(list);
converters.add(shmc);
//如下配置需要引入jackson组件,主要解决json输出,面向接口开发用的 不配的话不能正常接受json数据
var m2 = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
var m = new JavaTimeModule();
//LocalDateTime
m.addSerializer(LocalDateTime.class, new
LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
m.addDeserializer(LocalDateTime.class, new
LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//LocalDate
m.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
m.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
//LocalTime
m.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
m.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(m);
//java.util.Date //设置日期格式
SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
objectMapper.setDateFormat(smt);
m2.setObjectMapper(objectMapper);
//设置中文编码格式
m2.setSupportedMediaTypes(List.of(MediaType.parseMediaType("application/json;charset=UTF-8")));
converters.add(m2);
}
//配置视图
@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver rs = new InternalResourceViewResolver();
//配置视图路径
rs.setPrefix("/WEB-INF/static/");
//配置视图类型
rs.setSuffix(".jsp");
return rs;
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(internalResourceViewResolver());
}
}
//控制器类
@Controller
@RestController = @Controller@ResponseBody(不使用视图层,而直接输出数据)
//请求方法
@RequestMapping(value="/user/ok.do")支持所有访问方法
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
@PatchMapping
//RESTFUL 风格
@RequestMapping(value = "/abc/{nn}", method = RequestMethod.GET)
public String abc(@PathVariable("nn") String name) { return "user 用户中心首页 姓名:" + name;}
//传递参数
@RequestParam(value = "name", defaultValue = "World") String name接受表单数据
@RequestBody 接受请求负载数据
//配置类
@Configuration
@EnableWebMvc
@ComponentScan("cn.chenxiejia.controller")
@Import()导入类
@Bean
//取得请求的头信息
@RequestHeader HttpHeaders hs, @RequestHeader("token") String tk HttpServletRequest req, HttpServletResponse resp, HttpSession session, PrintWriter out
@Autowired
@Bean
@Primary public Sheet sheetB(){ return new SheetB(); }
@Qualifier("sheetA")//限定注入Bean ID
@Autowired
接下来演示几个常用的方式吧
@RestController //表示此类下的方法全部是直接输出到页面的 不使用视图
public class AppController {
@RequestMapping("/p1")
public Map<String, Object> p1(@RequestBody Map<String, Object> map) {
System.out.println(map);
return map;
}
@RequestMapping("/p4")
public String p4() {
return "张三";
}
@RequestMapping("/p2")
public void p2(@RequestParam("id") Integer id, @RequestParam("name") String name) {
System.out.println(id + "=" + name);
}
@RequestMapping(value = {"/p3", "/p3/{id}.html"})
public Map<Integer, Object> p3(@PathVariable(name = "id", required = false) Integer id, @RequestParam(name = "name", required = false, defaultValue = "张三") String name) {
Map<Integer, Object> map = new HashMap<>();
map.put(id, name);
return map;
}
@RequestMapping("/p5")
public void p5(PrintWriter out) {
out.println("中文效果");
}
}
再使用几个视图的
@Controller
public class UserController {
@RequestMapping("/u1")
public String u1() {
return "u";//这里使用视图所以返回的是查找u.jsp 具体什么文件看你的配置了
}
@ModelAttribute("name")//使用这个注解相当于request.setAttribute 每次都执行 不管是不是用
public String u2() {
return "张三丰";
}
@RequestMapping("/u2")
public ModelAndView u3() {
var mv = new ModelAndView();
//查找u2.jsp
mv.setViewName("u2");
//添加属性
mv.addObject("age", 18);
return mv;
}
@RequestMapping("/u4")
public String u4(Model m) {
m.addAttribute("gender", "性别男");
return "u";
}
@RequestMapping("/u6")
@ResponseBody
public Student u6() {
Student s = new Student();
s.setAge(18);
s.setGender("男");
s.setSid(1);
s.setName("jack");
return s;
}
@RequestMapping(("/u5"))
public ModelAndView u5() {
Student s = new Student();
s.setAge(18);
s.setGender("男");
s.setSid(1);
s.setName("jack");
ModelAndView mv = new ModelAndView();
mv.addObject("student", s);
mv.setViewName("u");
return mv;
}