面试-Java Web

Java Web

jsp简介:
HTML擅长显示页面,但是它并不能调用Java代码动态的生成内容;Servlet擅长调用Java程序,生成动态内容,但是Servlet不擅长显示页面。
 jsp(Java Server Pages)结合了HTML和Servlet的优点,本质上是运行在服务端的一个Servlet,Tomcat等Servlet容器会将jsp文件中的内容通过out.write()、out.print()等方法直接输出给浏览器,浏览器获取到的依然是一个html文档,然后再进行渲染等

JSP基本语法
1、模板元素
  模板元素指就是JSP中的HTML代码,模板元素的内容会作为out.write()的参数,直接输出到页面中,在HTML中怎么写,在JSP中就怎么写
2、 脚本片段
  脚本片段写在 <% %>中,可以在脚本片段中直接编写Java代码,脚本片段会原封不动的复制到java文件的service方法中的对应位置
3、表达式
  JSP的表达式写在<%= %>中,JSP表达式可以将一个对象直接输出到页面中,JSP表达式中的内容最终会作为out.print()方法的参数,输出到页面中
4、注释
  JSP的注释写在 <%-- --%>中
5、声明
  JSP中的声明写在<%! %>中
6、JSP指令
  JSP指令的格式:<%@ 指令名 属性名1=”属性值1” 属性名2=”属性值2” %>,举例:
  a、page指令:b、include指令c、taglib指令
7、JSP动作标签格式:
a、请求转发

b、动态包含

64. jsp 和 servlet 有什么区别?

  1. jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
  2. jsp更擅长表现于页面显示,servlet更擅长于逻辑控制。
  3. Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到。
  4. Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。

65. jsp 的9个内置对象分别是什么?作用是什么?

JSP有9个内置对象:

  • request:封装客户端的请求,其中包含来自GET或POST请求的参数;
  • response:封装服务器对客户端的响应;
  • pageContext:通过该对象可以获取其他对象;
  • session:封装用户会话的对象;
  • application:封装服务器运行环境的对象;
  • out:输出服务器响应的输出流对象;
  • config:Web应用的配置对象;
  • page:JSP页面本身(相当于Java程序中的this);
  • exception:封装页面抛出异常的对象。

66. 说一下 jsp 的 4 种作用域?

JSP中的四种作用域包括page、request、session和application,具体来说:

  • pageContext对象,最小的域对象,可以在当前页面中共享数据,一旦切换页面,则域中的属性就会丢失,该对象主要用来向标签中传递数据。
  • request对象,可以在一次请求中共享数据,一旦发送多次请求,则域中的属性就会丢失。主要用于在转发时共享数据(request域中属性在转发时有效,重定向时无效)。
  • session对象,可以在一次会话中共享数据,一旦会话结束则域中的属性丢失。会话:就是一次打开关闭浏览器的过程。
  • application对象,是最大的域对象,作用范围是整个项目,只要不关闭服务器则application域中的属性一直有效。

67. session 和 cookie 有什么区别?

1、存储位置不同

cookie的数据信息存放在客户端浏览器上。

session的数据信息存放在服务器上。

2、存储容量不同

单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。

对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。

3、存储方式不同

cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。

session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。

4、隐私策略不同

cookie对客户端是可见的,所以它是不安全的。

session存储在服务器上,不存在敏感信息泄漏的风险。

5、有效期上不同

可以通过设置cookie的属性,达到使cookie长期有效的效果。

Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。Tomcat中Session的默认失效时间为20分钟,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。session的过期时间是从session不活动的时候开始计算(如果session一直活动,session就总不会过期,从该Session未被访问,开始计时; 一旦Session被访问,计时清0);

6、服务器压力不同

cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。

session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。

7、浏览器支持不同

假如客户端浏览器不支持cookie:

cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。

session一般来说要配合cookie使用,如果用户浏览器禁用了cookie,那么只能使用URL重写来实现session的存储功能。

假如客户端支持cookie:

cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。

session只能在本窗口以及子窗口内有效。

8、跨域支持上不同

cookie支持跨域名访问。

session不支持跨域名访问。

68. 说一下 session 的工作原理?

session类似于map是键值对的形式存在的。通过session.getAttribute("name");获取对应的name参数信息

当用户访问到一个服务器,如果服务器启用Session,服务器就要为该用户创建一个session,在创建这个session的时候,服务器首先检查这个用户发来的请求里是否包含了一个session id,如果存在就去遍历服务端的session文件,找到与这个session id相对应的文件,文件中的key值便是session id,value为当前用户的一些信息,如果客户端请求里不包含有session id,则为该客户端创建一个session并生成一个与此session相关的session id。这个session id是唯一的、不重复的、不容易找到规律的字符串,这个session id将被在本次响应中返回到客户端保存,而保存这个session id的正是cookie通过set-cookie完成,此后的请求都会交换这个 Session ID,进行有状态的会话。

69. 如果客户端禁止 cookie 能实现 session 还能用吗?

Cookie与 Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案。
一般默认情况下,在会话中,服务器存储 session 的 session id 是通过 cookie 保存到浏览器里。

如果浏览器禁用了 cookie,浏览器请求服务器无法携带 session id,服务器无法识别请求中的用户身份,session就会失效。

但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session。

  1. 通过url重写把 session id 作为参数追加的原 url 中,后续的浏览器与服务器交互中携带 session id 参数。
  2. 服务器的返回数据中包含 session id,浏览器发送请求时,携带 session id 参数
  3. 通过 Http 协议其他 header 字段,服务器每次返回时设置该 header 字段信息,浏览器中 js 读取该 header 字段,请求服务器时,js设置携带该 header 字段。

70. spring mvc 和 struts 的区别是什么?

  • 拦截机制的不同

Struts2是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype,然后通过setter,getter吧request数据注入到属性。Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了,只能设计为多例。

SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又和一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。

Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。

  • 底层框架的不同

Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。Filter在容器启动之后即初始化;服务停止以后坠毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。

  • 性能方面

Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。所以,SpringMVC开发效率和性能高于Struts2

  • 配置方面

spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高。

71. 如何避免 sql 注入?

  1. PreparedStatement(简单又有效的方法)
    采用预编译语句集,输出的SQL是把整个参数用引号包起来,并把参数中的引号作为转义字符,从而避免了参数也作为条件的一部分,只要使用它的setXXX方法传值即可
    sql注入只对sql语句的准备(编译)过程有破坏作用,PreparedStatement参数不是简单拼接生成sql,而是先用?占位,之后再根据参数产生sql,因此也就避免了sql注入问题
//构建sql语句,以?作为占位符
String sq = "delete from table1 where id=? and name=?"
//创建PreparedStatement时就传入sql语句,实现了预编译
PreparedStatement ps = con.prepareStatement(sq); 
//设置sql语句的占位符的值,注意第一个参数位置是1不是0
ps.setString(1,"03");
ps.setString(2,"mao");          
//执行这个PreparedStatement   
ps.execute();            
  1. 使用正则表达式过滤传入的参数
  2. 字符串过滤
  3. JSP中调用该函数检查是否包函非法字符
  4. JSP页面判断代码
    使用javascript在客户端进行不安全字符屏蔽
    功能介绍:检查是否含有”‘”,”\”,”/”

72. 什么是 XSS 攻击,如何避免?

XSS攻击又称CSS,全称Cross Site Script  (跨站脚本攻击),其原理是攻击者向有XSS漏洞的网站中输入恶意的 HTML 代码,当用户浏览该网站时,这段 HTML 代码会自动执行,从而达到攻击的目的。XSS 攻击类似于 SQL 注入攻击,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。 XSS是 Web 程序中常见的漏洞,XSS 属于被动式且用于客户端的攻击方式。

XSS防范的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码。

73. 什么是 CSRF 攻击,如何避免?

CSRF(Cross-site request forgery)也被称为 one-click attack或者 session riding,中文全称是叫跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。

如何避免:

  1. 验证 HTTP Referer 字段
HTTP头中的Referer字段记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,而如果黑客要对其实施 CSRF
攻击,他一般只能在他自己的网站构造请求。因此,可以通过验证Referer值来防御CSRF 攻击。
  1. 使用验证码
关键操作页面加上验证码,后台收到请求后通过判断验证码可以防御CSRF。但这种方法对用户不太友好。
  1. 在请求地址中添加token并验证
CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于cookie中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有token或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于session之中,然后在每次请求时把token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。
对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue
而对于 POST 请求来说,要在 form 的最后加上 ,这样就把token以参数的形式加入请求了。
  1. 在HTTP 头中自定义属性并验证
这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。

你可能感兴趣的