目录
什么是SpringMVC?
什么是三层架构?
SpringMVC的执行流程
SpringMVC怎么样设定重定向和转发的
SpringMVC如何对时间格式的参数进行格式化
SpringMVC常用的注解有哪些
SpringMVC如何配置拦截器
过滤器和拦截器的区别?
SpringBoot中如何配置拦截器?
步骤一
HandlerInterceptor和HandlerInterceptorAdapter的区别
SpringMVC的Controller是单例还是多例,有没有并发安全问题,如何解决
RequestMapping 和 GetMapping有什么区别
Session和cookie有什么区别
Cookie的执行原理
Session执行原理
preparedStatement和Statement的区别
转发和重定向的区别
get和post请求的区别
什么是Restful?
SpringBoot
什么是Springboot?
SpringBoot如何做全局异常的统一处理
@SpringBootApplication注解的含义
spring-boot-starter-parent的作用?【没理解】
spring-boot-starter-web的作用【没理解】
你知道spring-boot-starter吗?【没理解】
SpringBoot中如何读取配置
SpringBoot中如何管理事务
什么是SpringMVC?
SpringMVC是Spring的一个模块,基于MVC(模型视图控制层)的一个框架。
MVC包含了Model模型、View视图、Controller层。
Model:模型,承载数据,并对用户提交请求进行逻辑处理的模块【可以说是包含了业务层和mapper/dao层】。其分为两类: 一类称为数据承载 Bean实体类,专门用户承载业务数据的,如 Student、User 等 一类称为业务处理 Bean:指 Service 或 Dao/mapper 对象,专门用于处理用户提交的请求进行逻辑处理返回给View层。
View:视图,为用户提供使用界面,与用户直接进行交互。
Controller:控制器,用于接收用户的请求转发给相应的 Model 进行逻辑处理,并根据 Model 的逻辑处理结果向用户提供相应响应。
MVC 架构程序的工作流程:
(1)用户通过 View 页面向服务端提出请求,可以是表单请求、超链接请求、AJAX 请求等
(2)服务端 Controller 控制器接收到请求后对请求进行解析,找到相应的 Model 对用户请求进行处理
(3)Model 处理后,将处理结果再交给 Controller
(4)Controller 在接到处理结果后,根据处理结果找到要作为向客户端发回的响应 View 页面。页面经渲染(数据填充)后,再发送给客户端。
什么是三层架构?
-
表现层(UI):直接跟前端打交互(一是接收前端ajax请求,二是返回json数据给前端)【Controller】
-
业务逻辑层(BLL):一是处理表现层转发过来的前端请求(也就是具体业务),二是将从数据访问层或持久层获取的数据返回到表现层。【Service】
-
数据访问层(DAL):直接操作数据库(针对数据的增添、删除、修改、查找等),并将获得的数据返回到上一层(也就是业务逻辑层)。【mapper】
SpringMVC的执行流程
SpringMVC怎么样设定重定向和转发的
重定向是指从一个页面跳转到另一个页面,是不同的请求,无法共享request中的数据,地址栏会发生改变。它是客户端行为(客户端进行重定向)。
转发是指从一个页面跳转到另一个页面,是相同的请求,可以共享request中的数据,地址栏不会发生改变,它是服务器行为(在服务器内部进行转发的)
springmvc默认是使用转发方式跳转的,且会经过视图解析器,我们也可以通过指定跳转方式,转发时在返回值前面加"forward:"关键字,重定向时在返回值前面加"redirect:",且此时就不会再经过视图解析器了
SpringMVC如何对时间格式的参数进行格式化
第一种需求,后台接收前台页面返回的string类型时间,要转换成的Date类型数据,可以使用@DateTimeFormat注解来接收参数【后端接收前端String类型时间】
第二种需求,后台将Date类型数据返回给前台页面,默认是返回时间戳,如果想要优雅的格式,可以在模型的Date字段或get方法上使用@JsonFormat注解,记住要导入jackson的相关依赖 【前端接收后端传递的时间】
SpringMVC常用的注解有哪些
@Controller:用来标识一个该类是控制层,并交给Spring容器进行管理
@Service:表示当前类是一个业务层,并交给Spring容器进行管理
@Repository:表示当前类是一个持久化层,并交给Spring容器管理
@Component:普通类的注解,并交给Spring容器进行管理
@RequestMapping:用来映射请求路径和参数
@ResponseBody:将方法的返回值转换成json格式返回给调用方。
@RequestBody:接收前端存放在数据包中的请求体中的数据。用对象进行接收
@PathVariable:接收请求中的参数【id等】,通常用在restful接口中
@RestController【复合注解】 = @Controller + @ResponseBody 在Controller层进行使用
@RestControllerAdvice:运用aop的思想,对全局异常做一些处理,比如结合@ExceptionHandler做全局异常捕获
SpringMVC如何配置拦截器
SpringMVC 的拦截器主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、登录验证等功能上
第1步,定义拦截器:通过自定义类实现 HandlerInterceptor 接口表明当前类是一个拦截器,并加上注解@component交给Spring容器进行管理,并且需要实现接口中的三个方法,preHandler方法是在请求到达处理器(就是在去访问springmvc后端controller)之前执行,postHandler方法是在请求经过处理器之后、解析试图之前执行,afterCompletion方法是在视图渲染之后(modelAndView)、返回客户端之前执行
第2步,配置拦截器:*在springmvc的配置文件xml中,配置需要拦截的路径,配置需要放行的路径。【白名单的直接不会进入拦截器】
过滤器和拦截器的区别?
过滤器Filter,实现Filter接口,基于javaweb,重写dofilter方法,web.xml进行配置,所有请求都会进行过滤:经过逻辑判断是否是登录请求和用户是否登录,才进行放行,
拦截器interceptor实现HandlerInteceptor,基于SpringMVC的,重写三个prehandle,posthandle,aftercompletion()方法,在其中定义黑白名单。白名单的不会进入拦截器,需要在springmvc中配置,配置白名单,直接【不会经过拦截器】,提高效率。
SpringBoot中如何配置拦截器?
第一步:定义拦截器:通过自定义一个类实现HandlerInteceptor接口,表示当前类是一个拦截器,并加上注解@component交给Spring容器进行管理,然后对其中的三个方法进行重写(非强制),在方法中编写业务拦截的规则。
第二步:配置拦截器:自定义一个配置类实现WebMvcConfigurer接口,并重写addInterceptors方法,其中配置需要拦截的路径和需要放行的路径
步骤一
创建inteceptor包,创建LoginInteceptor类
public class LoginInterceptor implements HandlerInterceptor {
/**
* 检测全局session对象中是否有uid数据,如果有则放行,若没有则重定向到登陆界面
* @param request 请求对象
* @param response 响应对象
* @param handler 处理器(url+Controller,映射)
* @return true则放行,false拦截
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
Object obj=request.getSession().getAttribute("uid");
if (obj==null){
//用户没有登录过系统
response.sendRedirect("/web/index.html");
return false;
}
return true;
}
}
步骤二
在config包下创建LoginInterceptorConfig类实现WebMvcConfigure类注册拦截器
registry.addInterceptor()用于注册拦截器
addPathPatterns(“/**”)意为拦截所有页面,参数是需要拦截的页面
excludePathPatterns()参数是不需要拦截的页面
/**
* 拦截器注册
*/
@Configuration
public class LoginInterceptorConfig implements WebMvcConfigurer {
HandlerInterceptor interceptor=new LoginInterceptor();
@Override
public void addInterceptors(InterceptorRegistry registry) {
List<String> patterns = new ArrayList<>();
patterns.add("/bootstrap3/**");
patterns.add("/css/**");
patterns.add("/images/**");
patterns.add("/js/**");
patterns.add("/web/register.html");
patterns.add("/web/index.html");
patterns.add("/web/login.html");
patterns.add("/web/product.html");
patterns.add("/users/reg");
patterns.add("/users/login");
registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns(patterns);
}
}
HandlerInterceptor和HandlerInterceptorAdapter的区别
HandlerInterceptor是拦截器的接口,我们可以实现该接口来自定义拦截器,HandlerInterceptorAdapter是抽象类【Adapter适配器】,它实现了HandlerInterceptor接口的子接口AsyncHandlerInterceptor,我们可以继承该类来自定义拦截器,它简化拦截器的实现,默认preHandler返回true
SpringMVC的Controller是单例还是多例,有没有并发安全问题,如何解决
在spring中,bean默认都是单例的,controller也是交给spring容器管理的一个bean,因此它也是单例的。
单例的好处是减少了创建对象和垃圾回收的时间,节省了内存资源,但同时单例会造成线程不安全的问题,因为当所有请求访问同一个controller实例,controller中的成员变量是所有线程公用的,某个线程如果修改了这个变量,别的请求再来拿这个变量就是修改后的值了
要解决这个问题,最直接有效的方式就是不要在controller中定义成员变量,如果你非要定义成员变量,两种方式
第一种,可以给controller上加注解@Scope("prototype"),将controller设置为多例模式,每次请求都重新实例化一个controller
第二种,使用ThreadLocal线程变量,让每一个线程都有自己独立的变量【原理】,对变量进行操作时,就不会出现线程安全问题。
线程+创建线程的方式+线程池的7大参数+线程池的执行流程+ThreadLocal+线程池的拒绝策略_GuGuBirdXXXX的博客-CSDN博客
RequestMapping 和 GetMapping有什么区别
@Getmapping是一个组合注解,是按照Restful风格规范的注解,
@GetMapping:等同于@RequestMapping(value = “”,method = RequestMethod.GET)
,意思是只接收get请求的方法
@Requestmapping如果没有指定请求方式,可以接收POST(数据存放在数据包的请求体中-分页) GET(数据存放在地址栏-findOne findAll) PUT(添加和修改) DELETE(删除) PATCH(批量删除)等各种类型的请求
Session和cookie有什么区别
会话:就是客户端和服务端的多次请求和响应的一个过程。
会话跟踪技术:在一次会话中,不同请求之间共享数据的技术。
突破口:数据保存在那儿
Cookie[从创建的时候开始计算]--(登录记住我的功能):将数据保存在客户端浏览器的会话跟踪技术,数据不太安全,而且数据大小【单个cookie不超过4k-20个cookie】有限制,并且保存的数据只能是字符串
【操作中文要进行编码和解码--编码【URLEncoder.encode("四川成都","UTF-8")】解码【URLDecoder.decode(cookie.getValue(),"UTF-8")】】
Session【从不操作的时候开始计算】(实现登录拦截--整个会话都可以显示用户名):将数据保存在服务器端的会话跟踪技术,数据相对安全,而且数据类型和大小没有限制。
但是如果服务器端保存的数据太多,会影响服务器的性能【所以服务器默认设置了Session的生命周期为30分钟】
拓展:HTTP是无状态的,就是说你这次访问服务器,关闭网页,再访问服务器,服务器是没有意识到又是你来访问。
那怎样保证将我们保持登录?这就需要使用Cookie技术进行存储用户名和密码。
说白了,cookie就是存储在浏览器的数据而已。
Cookie的执行原理
1浏览器向服务端**发送创建cookie的请求,服务器就会以set-cookie【name:张三,value:1234】的方式将cookie传回给浏览器。
2浏览器就会将cookie存储起来。
3当后续浏览器再次访问服务器的时候,就会自动将cookie传递给服务器。
Session执行原理
1.当浏览器访问服务器时,遇到创建Session的代码。服务器就会创建Session对象,然后为Session对象分配一个**jsessionid,再以Set-Cookie的方式将jsessionid传回给浏览器**
2.浏览器将**jsessionid保存起来**
3.当后续浏览器再次访问服务器时,会自动的将jsessionid**以cookie的方式传递给服务器**
4.服务器就可以根据**jsessionid找到session对象,获取session中的数据**
preparedStatement和Statement的区别
PreparedStatement呢,它是Statement的子接口
statement的sql语句使用字符串拼接,很容易出现sql诸如问题,而preparedStatement会进行预编译,使用?作为占位符,动态设置参数值替换占位符?,不容易出错易于维护
statement不对sql语句作处理,直接交给数据库,
而preparedStatement**会预编译sql语句,因此当多次执行时,只需DBMS【数据库管理系统】运行sql语句,而不必再编译,因此效率更高**
statement有sql注入风险,preparedStatement没有sql注入风险
转发和重定向的区别
转发:
是一次请求,可以共享同一组request和response数据,
地址栏不会发生变化,
转发不能到外部应用,
可以访问WEB-INF下的受限资源
重定向:
是多次请求,不能共享同一组request和response数据
地址栏会发生变化
重定向可以到外部应用
不可以访问WEB-INF下的受限资源
SpringMvc默认用的是转发【默认转发--会经过视图解析器(加上前缀和后缀)】:转发是内部转发,效率要高一些 。
【外部转发不会经过视图解析器return "forward:/xxx.jsp";】
SpringMvc中如果非要重定向:return "redirect:/xxx.jsp"; - 不会经过视图解析器
get和post请求的区别
get请求:
将请求数据在地址栏url【Uniform resources Locator -统一资源定位器】进行显示,不太安全
请求数据大小有限制-大约2kb(2048个字符)
请求数据类型只能是文本字符,不能上传文件
post请求:
将请求数据存放在请求体request body中,相对安全
请求数据没有限制
请求数据可以是任意类型,图片视频等,可以上传文件
在restful中,get一般用户查询搜索数据,post一般用户添加或者修改数据
什么是Restful?
Restful是一种接口编写规范,可以简单理解为:使用URL名词**定位资源,用HTTP动词(GET,POST。DELETE。PUT。PATCH)描述操作**。
注意:区分一个请求是不是相同的请求:1 请求方式【HTTP动词】+请求地址【URL名词定位资源】
SpringBoot
什么是Springboot?
定义:Springboot是一个简化配置(文件)和快速搭建项目的全新框架,目的就是用来简化Spring应用的初始搭建和开发过程**。**
注意:SpringBoot不是用来替换ssm的,只是用来快速搭建、简化配置和部署的全新框架
优势:
简单而言:SpringBoot使编码更简单,使配置更简单,使部署更简单,使监控更简单。
-
快速启动:SpringBoot内置Web(tomcat)容器,快速启动一个web项目(main方法启动)--不再每次都去等待tomcat启动
-
简化配置:Spring Boot提供了一种快速使用Spring的方式,简化xml配置(Mybatis除外-就是Mapper中写sql语句的),使用注解@SpringBootApplication加在主启动类上面,提高开发效率
-
入门容易:SpringBoot继承了原有Spring框架的优秀基因,写代码还是ssm代码。
/**
* 课程的启动类
* mapperscan在配置类中已经使用了
* */
//@SpringBootApplication(scanBasePackages = "cn.wmx") // 默认是扫描当前包及其子包,但是如果需要自定义扫描路径,就需要使用scanBasePackages
@SpringBootApplication
@EnableDiscoveryClient// @EnableEurekaClient 和 @EnableDiscoveryClient 的作用都是能够让注册中心发现、并扫描到该服务”
// @EnableEurekaClient只适用于Eureka作为注册中心 @EnableDiscoveryClient 可以是其他注册中心。
@EnableFeignClients // 开启feign接口的扫描
@EnableCaching // 开启SpringCache[基于缓存的注解]
public class CourseStarter {
public static void main(String[] args) {
SpringApplication.run(CourseStarter.class,args);
}
}
SpringBoot如何做全局异常的统一处理
我们使用了AOP(面向切面编程)的理念,通过自定义异常GlobleCustomedException然后继承RuntimeException(运行时异常),与系统的异常进行区分开来。然后自定义一个类,类上加上注解@RestControllerAdvice,自定义类中的方法上加上注解@ExceptionHandler(异常类.class),当@Controller注解下的类出现异常就会进入到我们自定义的这个类,进行匹配@ExceptionHandler(异常类.class)对应的异常类型,然后将错误信息和错误码进行封装返回给前台。这样就避免在Controller层写大量的try catch代码了
@SpringBootApplication注解的含义
@SpringBootApplication是SpringBoot项目的核心注解,目的是开启自动配置,并表示该类为主启动类。它包含三个子标签
-
@ComponentScan注解:开启ioc自动扫描注解,默认扫描当前包及其子包中@Controller,@Service等注解,并把这些bean加载到ioc器中
-
@EnableAutoConfiguration注解:启用springboot自动配置,自动扫描classpath目录下面所有jar中的spring.factories文件实现配置类注入到Spring容器当中。
-
@SpringBootConfiguration注解:表示该类为springboot配置类
spring-boot-starter-parent的作用?【没理解】
这是SpringBoot的父级依赖,提供了springboot统一的依赖管理和插件管理,引入依赖时可以省略版本号,parent中已经指定好了。(通过标签dependencyManagement管理依赖。)
但是在项目中,还需要通过 去导入具体的依赖才能使用
spring-boot-starter-web的作用【没理解】
给我们项目提供了webmvc、web、tomcat和json等能力。所以我们在没有配置tomcat,项目也能够跑起来。
你知道spring-boot-starter吗?【没理解】
这是Springboot的核心启动器,包含了自动配置、日志和YAML
SpringBoot中如何读取配置
方式一:使用注解@Value读取配置文件【yml中的】
方式二:使用@ConfigurationProperties读取配置文件
方式三:01、Environment获取属性值
Environment是用来读取应用程序运行时的环境变量(application.yml)的类,可以通过key-value的方式读取application.properties
SpringBoot读取配置文件的三种方法_程序员超时空的博客-CSDN博客_springboot读取配置文件的方式
SpringBoot中如何管理事务
事务(transaction)是指一个请求 可能涉及到对多个数据库的写操作,要保证多个数据库的数据的一致性,要么全部成功,要么全部失败。
在Springboot中,可以通过xml配置和注解配置(@Transactional)
xml方式通过配置DataSourceTransactionManager和transactionManager实现
注解方式配置通过在主启动类上加上@EnableTransactionManagement开启事务管理器,在具体的业务层service类上加上@Transactional 实现事务
更多推荐
SpringMVC+SpringBoot【面试题】
发布评论