介绍:spring mvc是基于servelet封装的一个表述层框架,用于简化前端数据的接收和后端数据的返回
DispatcherServlet(全局唯一的servlet,ceo)
handlerMapping(秘书,处理缓存)
handlerAdpater(经理,处理请求)
viewResovler(财务,处理视图解析)
一.基本使用
package com.Lemon.service;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Hello {
@RequestMapping("springMvc/hello") //对外访问的地址
@ResponseBody //直接返回字符串,不去做试图解析
public String hello(){
System.out.println("Hello");
return "Hello springMvc";
}
}
1.2编写配置类
将RequestMappingHandlerMapping,RequestMappingHandlerAdapter加入ioc,供springmvc调用
package com.Lemon.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@Configuration
@ComponentScan("com.Lemon.service")
public class MvcConfig {
@Bean
public RequestMappingHandlerMapping handlerMapping(){
return new RequestMappingHandlerMapping();
}
@Bean
public RequestMappingHandlerAdapter handlerAdapter(){
return new RequestMappingHandlerAdapter();
}
}
1.3 web文件的入口文件
替代web.xml文件写配置文件
package com.Lemon.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* web项目的入口文件,初始化ioc容器,设置dispatcherServlet的地址
* */
public class SpringMvcInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//设置service和mapper的配置文件
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
//设置项目对应的配置文件
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{MvcConfig.class};
}
// mvc自带的servlet访问地址
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
二.接收数据
2.1 .@RequestMapping详解
-
@RequestMapping声明一个可以被外部访问的方法,该方法返回前端需要的数据
-
@RequestMapping支持模糊匹配设置的路径
-
@RequestMapping设置在类上提取出地址公共前缀,类上的@RequestMapping非必要,方法上的@RequestMapping必要
-
@RequestMapping的method属性设置可请求方式,不符合方式的请求报 405异常,可简写为GetMapping,PostMapp,PutMapping,DeleteMapping
package com.Lemon.service;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Hello {
@RequestMapping("springMvc/hello") //对外访问的地址
@ResponseBody //直接返回字符串,不去做试图解析
public String hello(){
System.out.println("Hello");
return "Hello springMvc";
}
@RequestMapping(value = "springMvc/1",method = RequestMethod.GET)
public String test(){
return null;
}
@RequestMapping(value = "springMvc/2",method = RequestMethod.POST)
public String test2(){
return null;
}
}
2.2 param
param适合简单值,只支持字符串,,直接对应形参列表值传参
param接值四种方式
package com.Lemon.param;
import com.Lemon.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("param")
public class Param {
@RequestMapping("data")
@ResponseBody
//基础用法,至少要传一个值
public String data(String name,int age)
{
System.out.println("name = "+name+", age = "+age);
return "name = "+name+", age = "+age;
}
@RequestMapping("data1")
@ResponseBody
//@RequestParam表示必须传参,设置required = false后可设置默认值
public String data1(@RequestParam String name,
@RequestParam(required = false ,defaultValue = "1") int age)
{
System.out.println("name = "+name+", age = "+age);
return "name = "+name+", age = "+age;
}
@RequestMapping("data2")
@ResponseBody
//使用集合接值,必须要加@RequestParam注解
public String data2(@RequestParam List<String> names)
{
return "names = " + names;
}
@RequestMapping("data3")
@ResponseBody
//使用对象接值,使用最广泛
public String data3(User user)
{
return user.toString();
}
}
2.3.路径参数接收
//路径加{}
@RequestMapping("{name}/{age}")
@ResponseBody
//形参列表加@PathVariable注解
public String data4(@PathVariable String name,@PathVariable int age){
return name + " " + age;
}
localhost:8080/param/data3/?name=ergouzi&age=18
localhost:8080/param/ergouzi/18
对比普通传参方法路径传参可以使路径简洁可读性提高
2.4.json
原生的java api只支持路径传参和param传参,所以使用json需要先导入依赖并在配置类上加入@EnableWebMvc注解(为handAdapter配置json转化器)
@RequestMapping("data5")
@ResponseBody
public String data5(@RequestBody User user){
return user.toString();
}
并且,在配置类中加入@EnableWebMvc后,该注解会自动向ioc添加handlerMapping(秘书)和handlerAdapter(经理),不需要自己再添加
所以web文件的配置类中一般都会加入该注解
@EnableWebMvc
@Configuration
@ComponentScan("com.Lemon.param")
public class MvcConfig {
// @Bean
// public RequestMappingHandlerMapping handlerMapping(){
// return new RequestMappingHandlerMapping();
// }
//
// @Bean
// public RequestMappingHandlerAdapter handlerAdapter(){
// return new RequestMappingHandlerAdapter();
// }
}
此外还可以接收cookie,请求头,原生对象等,除了param类型不需要加额外注解,其他所有类型的数据都要在形参列表加上额外注解
三.返回数据
3.1.返回json数据
返回Json数据一般用于前后端分离项目,也最常用,需要先导入jackson-databind依赖
package com.Lemon.json;
import com.Lemon.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
@Controller
@ResponseBody //json数据都不需要走视图解析器
@RequestMapping("json")
public class Json {
@RequestMapping("data")
public User data(){
User user = new User();
user.setName("ergouzi");
user.setAge(13);
return user; //json数据直接返回实体类即可,由handlerAdapter(经理)完成数据的解析
}
@RequestMapping("data2")
public List<User> data2(){
User user = new User();
user.setName("ergouzi");
user.setAge(13);
List<User> users = new ArrayList<User>();
users.add(user);
return users; //集合类型也可以直接返回
}
}
四.静态资源
将静态资源放在webapp下,但是不要放在web-inf下(不会打包)
package com.Lemon.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@EnableWebMvc
@Configuration
@ComponentScan("com.Lemon.json")
public class MvcConfig implements WebMvcConfigurer {
// @Bean
// public RequestMappingHandlerMapping handlerMapping(){
// return new RequestMappingHandlerMapping();
// }
//
// @Bean
// public RequestMappingHandlerAdapter handlerAdapter(){
// return new RequestMappingHandlerAdapter();
// }
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
开启configureDefaultServletHandling,将静态资源交给HandlerMapping(秘书)
五.RESTful
RESTful是标准的http协议使用方式,是一种设计风格
要求:
- url不带动作,只做标识(单一参数路径传参,范围参数param,其他json),请求方式/模块/…
- 对应的请求方式做对应的事,get查找,post增加,put更新,delete删除
package com.Lemon.RESTful.controll;
import com.Lemon.RESTful.pojo.User;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ResponseBody
@RequestMapping("user")
public class UserController {
@GetMapping
public List<User> page(@RequestParam(required = false,defaultValue = "1") int page,
@RequestParam(required = false,defaultValue = "10") int size) {
return null;
}
@PostMapping
public User save(@RequestBody User user){
return null;
}
@GetMapping("{id}")
public User get(@PathVariable int id){
return null;
}
@DeleteMapping("{id}")
public User delete(@PathVariable int id){
return null;
}
@GetMapping("search")
public List<User> services(@RequestParam(required = false,defaultValue = "1") int page,
@RequestParam(required = false,defaultValue = "10") int size){
return null;
}
}
访问时使用GET/user/…这种风格访问
六.拦截器
先写拦截类
package com.Lemon.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 MyInterceptor implements HandlerInterceptor {
/**
* request 请求对象
* response 返回对象
* handler 方法对象
* ModelAndView 返回的视图和共享域对象
* true为放行
* 三个方法分别执行与方法前,方法后,方法后必定执行
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
在Mvcconfig中注册拦截器,重写addInterceptors方法即可
/**
* 直接添加为拦截所有方法
* addPathPatterns可指定路径拦截
* */
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor());
//registry.addInterceptor(new MyInterceptor()).addPathPatterns("data/user");
}
七.参数校验
-
导入hibernate
-
实体类属性加入校验注解
-
handler方法中加入@validated注解(param|json数据都生效)
-
在参数后加入 BindingResult result可利用result返回自定义的错误码,否则默认直接返回异常给前端
@PostMapping("post")
public List<User> update(@Validated @RequestBody User user , BindingResult result){
return null;
}