赞
踩
提示:SpingMVC是用来替换Servlet,用来完成表现层操作的
首先得明白SpringMVC能干什么:1.请求与响应
SpringMVC是一种基于Java实现MVC模型得轻量型Web框架。
1.导入SpringMVC、servlet、Tomcat的坐标
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
2.创建控制器类(创建Controller文件夹,并在文件夹下创建控制类)
-------2.1在控制类中使用@Controller定义一个Bean
-------2.2在控制类中使用@RequestMapping设置当前操作得访问路径
-------2.3在控制类中使用@ResponseBody设置当前操作得返回值类型
@Controller //使用@Controller定义一个Bean
public class UserController {
@RequestMapping("/save") //设置当前操作得访问路径
@ResponseBody //设置当前操作得返回值类型
public String save(){
return "";
}
@RequestMapping("/delete") //设置当前操作得访问路径
@ResponseBody //设置当前操作得返回值类型
public String delete(){
return "";
}
}
3.创建配置类SpringMVCConfig加载controller对应的bean,去扫描控制类所在的文件夹
@Configuration
@ComponentScan("com.itheima.controller")//这里面可以设数组
public class SpringMVCConfig {
}
4.定义一个Servlet容器启动配置类ServletContainerslnitConfig,在里面加载Spring的配置
//定义一个Servlet容器启动配置类,在里面加载Spring的配置 public class ServletContainerslnitConfig extends AbstractDispatcherServletInitializer { //加载SpringMVCX的配置的 @Override protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMVCConfig.class);//注册容器 return ctx; } //设置哪些请求归属springMVC处理 @Override protected String[] getServletMappings() { return new String[]{"/"}; //表示所有请求归MVC处理 } //集在spring容器配置(可以不用管) @Override protected WebApplicationContext createRootApplicationContext() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringConfig.class);//<-----注意这里 return ctx; } }
如何控制Spring的配置类中不扫描Controller包下的类
(1)SpringMVC加载其相关bean(表现层bean),也就是controller包下的类
(2)Spring控制的bean有业务bean(Service)、功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
方式一:修改Spring配置类,设定扫描范围为精准范围。
@Configuration
@ComponentScan({"com.itheima.service","comitheima.dao"})
public class SpringConfig {
}
//设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
//excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value="com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class <---表示类上标注@Controller的全部排除
)
)
public class SpringConfig {
}
注意:在Controller包下有2个类,如果2个类中各有一个方法,且方法名一样,运行起来就会报错,如何处理?
解决方法:定义请求路径的前缀
@Controller //类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径 @RequestMapping("/user") //<---注意这里,直接在这里定义请求路径的前缀 public class UserController { //请求路径映射 @RequestMapping("/save") @ResponseBody public String save(){ System.out.println("user save ..."); return "{'module':'user save'}"; } //请求路径映射 @RequestMapping("/delete") @ResponseBody public String delete(){ System.out.println("user delete ..."); return "{'module':'user delete'}"; } }
(1)注意一点,不管是Get获取参数还是P
在容器启动配置类ServletContainerslnitConfig重写getServletFilters()方法
//乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
//普通参数:请求参数名与形参名不同时,使用@RequestParam注解关联请求参数名称与形参名称之间的关系
@RequestMapping("/commonParamDifferentName")
@ResponseBody
//@RequestParam("name") String userName意思就是把传递过来的参数 赋给 形参中的参数
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
//POJO参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
//日期参数
//使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1, //设置传进来的参数类型
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
//响应页面/跳转页面
//返回值为String类型,设置返回值为页面名称,即可实现页面跳转
@RequestMapping("/toJumpPage") //<----注意使用的是@RequestMapping
public String toJumpPage(){ //<----注意使用的是String类型
System.out.println("跳转页面");
return "page.jsp";
}
//响应文本数据
//返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
@RequestMapping("/toText")
@ResponseBody //<----注意使用的是@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
//响应POJO对象(Json)、要导入JackSon坐标
//返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonPOJO")
@ResponseBody //<----注意使用的是@ResponseBody
public User toJsonPOJO(){ //<---要把方法的返回值设置成Pojo类型
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user; //<---要把方法的返回值设置成Pojo的对象
}
//响应POJO集合对象(Json)、要导入JackSon坐标 //返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解 @RequestMapping("/toJsonList") @ResponseBody public List<User> toJsonList(){ //<---要把方法的返回值设置成Pojo集合的类型 System.out.println("返回json集合数据"); User user1 = new User(); user1.setName("传智播客"); user1.setAge(15); User user2 = new User(); user2.setName("黑马程序员"); user2.setAge(12); List<User> userList = new ArrayList<User>(); userList.add(user1); userList.add(user2); return userList;
//设置当前请求方法为POST,表示REST风格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE) //{id}和方法中的形参要一致
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
在Controller文件夹下创建SpringMvcSupport类进行配置
@Configuration //这个类一定要能被SpingMVC配置类扫描
public class SpringMvcSupport extends WebMvcConfigurationSupport {
//设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
1.在controller包下创建interceptor包,并在其下自定义拦截器ProjectInterceptor,拦截器必须要实现HandlerInterceptor接口,该拦截器必须要能被SpringMVCConfig所扫描
@Component //定义拦截器类,实现HandlerInterceptor接口 //注意当前类必须受Spring容器控制,也就是必须被SpringMVC所扫描 public class ProjectInterceptor implements HandlerInterceptor { @Override //原始方法调用前执行的内容 //返回值类型可以拦截控制的执行,true放行,false终止 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String contentType = request.getHeader("Content-Type"); HandlerMethod hm = (HandlerMethod)handler; System.out.println("preHandle..."+contentType); return true; } @Override //原始方法调用后执行的内容 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle..."); } @Override //原始方法调用完成后执行的内容 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion..."); } }
2.在config包下创建SpringMvcSupport类(配置拦截器类)
@Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Autowired private ProjectInterceptor projectInterceptor; @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); //<---SpringMVC放行静态资源 } @Override protected void addInterceptors(InterceptorRegistry registry) { //<---要覆盖重写的方法 //配置拦截器 registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");//所有books开头的文件全拦截 } }
3.SpringMVC添加SpringMvcSupport包扫描
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig{
}
4.可以对2,3步骤进行优化,直接在SpringMvcConfig类中实现WebMvcConfigurer接口,并在其中重写SpringMvcSupport中的方法即可
@Configuration @ComponentScan({"com.itheima.controller"}) @EnableWebMvc //实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性 public class SpringMvcConfig implements WebMvcConfigurer { @Autowired private ProjectInterceptor projectInterceptor; @Autowired private ProjectInterceptor2 projectInterceptor2; @Override public void addInterceptors(InterceptorRegistry registry) { //配置多拦截器 registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*"); registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*"); } }
//自定义异常处理器,用于封装异常信息,对异常进行分类 public class SystemException extends RuntimeException{ private Integer code; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public SystemException(Integer code, String message) { super(message); this.code = code; } public SystemException(Integer code, String message, Throwable cause) { super(message, cause); this.code = code; } }
2.将其他异常包成自定义异常,
假如在BookServiceImpl的getById方法抛异常了,该如何来包装呢?
public Book getById(Integer id) {
//模拟业务异常,包装成自定义异常
if(id == 1){
throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
}
//模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
try{
int i = 1/0;
}catch (Exception e){
throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
}
return bookDao.getById(id);
}
3.处理器类中处理自定义异常
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器 @RestControllerAdvice //该类一定要能被SpringMVC配置类扫描到 public class ProjectExceptionAdvice { //@ExceptionHandler用于设置当前处理器类对应的异常类型 @ExceptionHandler(SystemException.class)//系统异常 public Result doSystemException(SystemException ex){ //记录日志 //发送消息给运维 //发送邮件给开发人员,ex对象发送给开发人员 return new Result(ex.getCode(),null,ex.getMessage()); } @ExceptionHandler(BusinessException.class) //业务异常 public Result doBusinessException(BusinessException ex){ return new Result(ex.getCode(),null,ex.getMessage()); } //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常 @ExceptionHandler(Exception.class) //其他异常 public Result doOtherException(Exception ex){ //记录日志 //发送消息给运维 //发送邮件给开发人员,ex对象发送给开发人员 return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!"); } }
注意:以下是重中之重
1.先在resources文件夹下创建Jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1
jdbc.username=root
jdbc.password=1234
2.在config文件夹下创建JdbcConfig类,配置Jdbc
//主要是为了创建数据源 public class JdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean public DataSource dataSource(){ DruidDataSource dataSource = new DruidDataSource(); //造druid的数据源 dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
3.在config文件夹下创建MybatisConfig类,配置Mybatis
public class MybatisConfig { @Bean //数据源扫描 public SqlSessionFactoryBean sqlSession(DataSource dataSource) { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); //加载JDBC数据源 factoryBean.setTypeAliasesPackage("com.itheima.domain"); //扫描实体类 return factoryBean; } @Bean //扫描映射 public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setBasePackage("com.itheima.dao"); //扫描到数据层 return msc; } }
4.在config文件夹下创建SpringConfig类,扫描Jdbc与Mybatis配置
@Configuration
@ComponentScan({"com.itheima.service"})
@PropertySource("jdbc.properties") //引入JDBC配置文件
@Import({JdbcConfig.class, MybatisConfig.class}) //加载2个配置类
public class SpringConfig {
}
1.在config文件夹下创建SpringMvcConfig类,配置SpringMvc
@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
2.在config文件夹下创建容器类
//web容器配置类 public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"};
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。