Javaweb基础
常见Http状态码
200 成功返回状态
301 永久重定向,被请求的资源永久移动到新位置
302 临时重定向,被请求的资源临时移动到新的位置,项目中使用了oauth2,对目标资源访问无权限时就会见到,它是会重定向到授权地址
401 无权限访问
403 禁止访问,服务器已经接收到请求,但拒绝执行
404 找不到该资源
500 服务器内部错误 zuul找不到服务名就会见到
503 服务器内部错误 服务器维护或者过载
504 网关超时
Servlet的生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
- Servlet 初始化后调用 init () 方法。
- Servlet 调用 service() 方法来处理客户端的请求。
- Servlet 销毁前调用 destroy() 方法。
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
什么是过滤器?怎么创建一个过滤器
过滤器:在请求发送之后,处理之前对请求的一次拦截,可以更改请求状态或者参数值等。
创建过滤器:实现filter接口,重写doFilter方法,最后在web.xml中配置过滤器
讲一下Session的工作原理
服务端的session id会自动写入客户端的cookie中,每次请求客户端回自动把cookie带入后台,后台自动根据cookie中的sessionid就能找到session
Session和cookie有什么区别
session和cookie都是为了弥补http协议的无状态特性,解决会话问题
session是以ConcurrentHashMap结构存储在服务器端,同时生成一个sessionid返回客户端并存放到cookie中
cookie是将数据存储在客户浏览器端
session占用服务器的性能,但安全性较高,使用cookie减轻服务器的压力,但有被用户篡改风险因此安全性较低
说说preparedStatement和Statement的区别
statement的sql语句使用字符串拼接,很容易出错,而preparedStatement使用?作为占位符,不容易出错易于维护
statement不对sql语句作处理,直接交给数据库,而preparedStatement支持预编译,事先将编译好的sql语句放到数据库端,相当于缓存,因此效率更高
statement有sql注入风险,preparedStatement没有sql注入风险
请求转发和重定向的区别
转发是一次请求,可以共享同一组request和response,重定向是多次请求,不能共享同一组request和response
转发地址栏不会发生变化,重定向地址栏会发生变化
转发不能到外部应用,重定向可以到尾部应用
如果我们需要数据共享,使用转发,如果需要访问内部资源(WEB-INF),使用转发,如果需要跨域到外部资源,必须使用重定向
get和post请求的区别
最直观的区别,get把参数包含在url中,post是把参数放到request body中
post相对于get更安全,post发送的数据更大,get有url的长度限制
post更发送更多的数据类型,get只能发送ASCII字符
在restful中,get一般用户查询搜索数据,post一般用户添加或者修改数据
JSP的原理
jsp的本质就是servlet,每个JSP文件都回被编译成一个Serverlet去执行,在该Serverlet会对JSP中的动态内容进行替换,静态部分是标准的html,动态部分是java程序
SpringMVC部分
SpringMVC怎么样设定重定向和转发的
重定向是指将用户从当前请求重新定向到一个视图页面,或者是一个handler处理请求,以前的request域中信息全部失效,同时地址栏会发生变化,它是客户端行为
转发是指将用户从当前请求转发给另一个视图页面或者handler处理请求,以前的request域可以共享,地址栏不会发生变化,它是服务器行为
springmvc默认是使用转发方式跳转的,且会默认经过视图解析器,我们也可以通过指定,转发时在返回值前面加"forward:",重定向时在返回值前面加"redirect:",且此时就不会再经过视图解析器了
SpringMVC如何对时间格式的参数进行格式化
第一种需求,后台接收前台页面返回的string类型时间,要转换成的Date类型数据,可以使用@DateTimeFormat注解来接收参数
第二种需求,后台将Date类型数据返回给前台页面,默认是返回时间戳,如果想要优雅的格式,可以在模型的Date字段或get方法上使用@JsonFormat注解
SpringMVC常用的注解有哪些
@Controller:用来标识一个类是控制器类
@RequestMapping:用来映射请求路径和参数
@ResponseBody:将返回值放到responsebody中,通常返回json或者xml格式数据
@RequestBody:将前台请求参数转换成对象
@PathVariable:接收路径参数,通常用在restful接口中
@RestController:@Controller和@ResponseBody的组合注解
@ControllerAdvice:运用aop的思想,对全局做一些处理,比如结合@ExceptionHandler做全局异常捕获
如何定义SpringMVC的拦截器
SpringMVC 的拦截器主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、判断登录等功能上
第1步,定义拦截器:可以实现 HandlerInterceptor 接口来自定义拦截器,接口定义了三个方法,preHandler方法是在请求到达处理器之前执行,postHandler方法是在请求经过处理器之后、解析试图之前执行,afterCompletion方法是在视图渲染之后、返回客户端之前执行
第2步,配置拦截器:在springmvc的配置文件xml中,配置所有拦截路径,以及需要放行的路径
HandlerInterceptor和HandlerInterceptorAdapter的区别
HandlerInterceptor是接口,我们可以实现该接口来定义拦截器,HandlerInterceptorAdapter是抽象类,它实现了HandlerInterceptor接口的子接口AsyncHandlerInterceptor,我们可以继承该类来定义拦截器,它简化拦截器的实现,默认preHandler返回true
SpringMVC的执行原理
1.Http请求:客户端请求提交到DispatcherServlet-前端控制器
2.寻找处理器:由DispatcherServlet调用HandlerMapping-处理器映射器,根据url找到对应的的Handler
3.调用处理器:DispatcherServlet指定HandlerAdapter-处理器适配器去调用Handler
4.调用业务处理和返回结果:Handler调用业务逻辑处理完成后,返回ModelAndView
5.处理视图映射并返回模型: DispatcherServlet查询一个或多个ViewResoler-视图解析器,找到ModelAndView指定的视图
6.Http响应:将结果显示到客户端
SpringMVC的Controller是单例还是多例,有没有并发安全问题,如何解决
在spring中,bean默认都是单例的,controller也是交给spring容器管理的一个bean,因此它也是单例的。
单例的好处是减少了创建对象和垃圾回收的时间,节省了内存资源,但同时单例会造成线程不安全的问题,因为当所有请求访问同一个controller实例,controller中的成员变量是所有线程公用的,某个线程如果修改了这个变量,别的请求再来拿这个变量就编程修改后的值了
要解决这个问题,最直接有效的方式就是不要在controller中定义成员变量,如果你非要定义成员变量,两种方式
第一种,可以给controller上加注解@Scope("prototype"),将controller设置为多例模式,每次请求都重新实例化一个controller
第二种,使用ThreadLocal变量,让每一个线程都有自己独立的变量
RequestMapping 和 GetMapping有什么区别
@Getmapping是一个组合注解,即是@RequestMapping(method = RequestMethod.GET)的缩写,意思是只接收get请求的方法
@Requestmapping如果没有指定请求方式,可以接收get,put等各种类型的请求