java web

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GwZYHHrI-1571882317223)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1568164588732.png)]

Tomcat

Tomcat的缺省端口是多少,怎么修改

server.xml-port

Tomcat 有哪几种Connector 运行模式(优化)?

  1. bio(blocking I/O)
  2. nio(non-blocking I/O)
  3. apr(Apache Portable Runtime/Apache可移植运行库)

相关解释:

  • bio: 传统的Java I/O操作,同步且阻塞IO。

  • nio: JDK1.4开始支持,同步阻塞或同步非阻塞IO

  • aio(nio.2): JDK7开始支持,异步非阻塞IO

  • apr: Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高Tomcat对静态文件的处理性能

    Tomcat有几种部署方式

  1. 直接把Web项目放在webapps下,Tomcat会自动将其部署
  2. 在server.xml文件上配置 <Context>节点,设置相关的属性即可
  3. 通过Catalina来进行配置:进入到conf\Catalina\localhost文件下,创建一个xml文件,该文件的名字就是站点的名字。编写XML的方式来进行设置。

get方式和post方式有何区别

get方式和post方式有何区别

数据携带上:

  • GET方式:在URL地址后附带的参数是有限制的,其数据容量通常不能超过1K。
  • POST方式:可以在请求的实体内容中向服务器发送数据,传送的数据量无限制。

请求参数的位置上:

  • GET方式:请求参数放在URL地址后面,以?的方式来进行拼接
  • POST方式: 请求参数放在HTTP请求包中

用途上:

  • GET方式一般用来获取数据
  • POST方式一般用来提交数据
    • 首先是因为GET方式携带的数据量比较小,无法带过去很大的数量
    • POST方式提交的参数后台更加容易解析(使用POST方式提交的中文数据,后台也更加容易解决)
    • GET方式比POST方式要快,详情可看:https://www.cnblogs.com/strayling/p/3580048.html

Servlet

什么是servlet,为什么用servlet

Servlet其实就是一个遵循Servlet开发的java类。Serlvet是由服务器调用的运行在服务器端。我们编写java程序想要在网上实现 聊天、发帖、这样一些的交互功能,普通的java技术是非常难完成的。sun公司就提供了Serlvet这种技术供我们使用。

Servlet带给我们最大的作用就是能够处理浏览器带来HTTP请求,并返回一个响应给浏览器,从而实现浏览器和服务器的交互

Servlet生命周期

Servlet生命周期可分为5个步骤

  1. 加载Servlet。当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
  2. 初始化。当Servlet被实例化后,Tomcat会调用init()方法初始化这个对象
  3. 处理服务。当浏览器访问Servlet的时候,Servlet 会调用service()方法处理请求
  4. 销毁。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁
  5. 卸载。当Servlet调用完destroy()方法后,等待垃圾回收。如果有需要再次使用这个Servlet,会重新调用init()方法进行初始化操作

  • 简单总结:只要访问Servlet,service()就会被调用。init()只有第一次访问Servlet的时候才会被调用。destroy()只有在Tomcat关闭的时候才会被调用。

实现Servlet接口编写Servlet程序

  • 创建一个自定义类,实现Serlvet接口

  • 我们发现有5个方法需要重写,有init【初始化】,destroy【销毁】,service【服务】,ServletConfig【Servlet配置】,getServletInfo【Serlvet信息】。

  • 重写service()方法调用ServletResponse对象的方法向浏览器输出HelloWorld

    如:servletRespnse.getWtiter().write(“Hello World”);

  • 配置xml文件,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-reBdVDuC-1571882317225)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1568166156978.png)]

继承HttpServlet编写Servlet程序

在上面我们实现Servlet接口,要实现5个方法。这样太麻烦了!而HttpServlet类已经实现了Servlet接口的所有方法,编写Servlet时,只需要继承HttpServlet,重写你需要的方法即可,并且它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大

一般我们开发的时候,都是重写doGet()和doPost()方法的。对于idea而言,创建Servlet的时候已经帮你重写好了

img

HTTP1.0和HTTP1.1的区别

HTTP1.0协议中,客户端与web服务器建立连接后,只能获得一个web资源【短连接,获取资源后就断开连接】

HTTP1.1协议,允许客户端与web服务器建立连接后,在一个连接上获取多个web资源【保持连接】

节约带宽:HTTP 1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。

**HOST域:**web server上的多个虚拟站点可以共享同一个ip和端口。

HTTP1.0是没有host域的,HTTP1.1才支持这个参数。

HTTP1.1 HTTP 2.0主要区别

  • 多路复用

HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。

  • 数据压缩

HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

  • 服务器推送

当我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。

服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。

HttpServletResponse与HttpServletRequest

doGet与doPost方法的两个参数是什么

(HttpServletResponse与HttpServletRequest)

HttpServletResponse:封装了与响应相关的信息

HttpServletRequest:封装了与请求相关的信息

获取页面的元素的值有几种方式,分别说一下

  1. request.getParameter() 返回客户端的请求参数的值
  2. request.getParameterNames() 返回所有可用属性名的枚举
  3. request.getParameterValues() 返回包含参数的所有值

request.getAttribute()和request.getParameter()区别

  • 用途上:
    • request.getAttribute(), 一般用于获取request域对象的数据(在跳转之前把数据使用setAttribute来放到request对象上)
    • request.getParameter(), 一般用于获取客户端提交的参数
  • 存储数据上:
    • request.getAttribute()可以获取Objcet对象
    • request.getParameter()只能获取字符串(这也是为什么它一般用于获取客户端提交的参数)

forward和redirect的区别

  • 实际发生位置不同,地址栏不同
    • 转发是发生在服务器的
    • 转发是由服务器进行跳转的,细心的朋友会发现,在转发的时候,浏览器的地址栏是没有发生变化的,在我访问Servlet111的时候,即使跳转到了Servlet222的页面,浏览器的地址还是Servlet111的。也就是说浏览器是不知道该跳转的动作,转发是对浏览器透明的。通过上面的转发时序图我们也可以发现,实现转发只是一次的http请求一次转发中request和response对象都是同一个。这也解释了,为什么可以使用request作为域对象进行Servlet之间的通讯。
  • 重定向是发生在浏览器的 - 重定向是由浏览器进行跳转的,进行重定向跳转的时候,浏览器的地址会发生变化的。曾经介绍过:实现重定向的原理是由response的状态码和Location头组合而实现的。这是由浏览器进行的页面跳转实现重定向会发出两个http请求request域对象是无效的,因为它不是同一个request对象
  • 用法不同:
  • 很多人都搞不清楚转发和重定向的时候,资源地址究竟怎么写。有的时候要把应用名写上,有的时候不用把应用名写上。很容易把人搞晕。记住一个原则: 给服务器用的直接从资源名开始写,给浏览器用的要把应用名写上
    • request.getRequestDispatcher("/资源名 URI").forward(request,response)
    • 转发时"/"代表的是本应用程序的根目录【zhongfucheng】 - response.send("/web应用/资源名 URI"); - 重定向时"/"代表的是webapps目录
  • 能够去往的URL的范围不一样:
    • 转发是服务器跳转只能去往当前web应用的资源
    • 重定向是服务器跳转,可以去往任何的资源
  • 传递数据的类型不同
    • 转发的request对象可以传递各种类型的数据,包括对象
    • 重定向只能传递字符串
  • 跳转的时间不同
    • 转发时:执行到跳转语句时就会立刻跳转
    • 重定向:整个页面执行完之后才执行跳转

那么转发(forward)和重定向(redirect)使用哪一个?

  • 根据上面说明了转发和重定向的区别也可以很容易概括出来**。转发是带着转发前的请求的参数的。重定向是新的请求**。

典型的应用场景:

  1. 转发: 访问 Servlet 处理业务逻辑,然后 forward 到 jsp 显示处理结果,浏览器里 URL 不变
  2. 重定向: 提交表单,处理成功后 redirect 到另一个 jsp,防止表单重复提交,浏览器里 URL 变了

tomcat容器是如何创建servlet类实例?用到了什么原理?

tomcat容器是如何创建servlet类实例?用到了什么原理

  1. 当容器启动时,会读取在webapps目录下所有的web应用中的web.xml文件,然后对 xml文件进行解析,并读取servlet注册信息。然后,将每个应用中注册的servlet类都进行加载,并通过 反射的方式实例化。(有时候也是在第一次请求时实例化)
  2. 在servlet注册时加上1,如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。

对象的发布与逸出

发布(publish) 使对象能够在当前作用域之外的代码中使用

逸出(escape) 当某个不应该发布的对象被发布了

常见逸出的有下面几种方式:

  • 静态域逸出
  • public修饰的get方法
  • 方法参数传递
  • 隐式的this

静态域逸出:

img

public修饰get方法:

img

方法参数传递我就不再演示了,因为把对象传递过去给另外的方法,已经是逸出了~

下面来看看该书给出this逸出的例子

img

逸出就是本不应该发布对象的地方,把对象发布了。导致我们的数据泄露出去了,这就造成了一个安全隐患!理解起来是不是简单了一丢丢?

2.1安全发布对象

上面谈到了好几种逸出的情况,我们接下来来谈谈如何安全发布对象

安全发布对象有几种常见的方式:

  • 在静态域中直接初始化public static Person = new Person();
    • 静态初始化由JVM在类的初始化阶段就执行了,JVM内部存在着同步机制,致使这种方式我们可以安全发布对象
  • 对应的引用保存到volatile或者AtomicReferance引用中
    • 保证了该对象的引用的可见性和原子性
  • 由final修饰
    • 该对象是不可变的,那么线程就一定是安全的,所以是安全发布~
  • 由锁来保护
    • 发布和使用的时候都需要加锁,这样才保证能够该对象不会逸出

什么是cookie?Session和cookie有什么区别?

什么是cookie?

Cookie是由W3C组织提出,最早由netscape社区发展的一种机制

  • 网页之间的交互是通过HTTP协议传输数据的,而Http协议是无状态的协议。无状态的协议是什么意思呢?一旦数据提交完后,浏览器和服务器的连接就会关闭,再次交互的时候需要重新建立新的连接
  • 服务器无法确认用户的信息,于是乎,W3C就提出了:给每一个用户都发一个通行证,无论谁访问的时候都需要携带通行证,这样服务器就可以从通行证上确认用户的信息。通行证就是Cookie
  • 从存储方式上比较
    • Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码。
    • Session可以存储任何类型的数据,可以把Session看成是一个容器
  • 从隐私安全上比较
    • Cookie存储在浏览器中,对客户端是可见的*。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
    • Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。
  • 从有效期上比较
    • Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的
    • Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。
  • 从对服务器的负担比较
    • Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
    • Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪。
  • 从浏览器的支持上比较
    • 如果浏览器禁用了Cookie,那么Cookie是无用的了!
    • 如果浏览器禁用了Cookie,Session可以通过URL地址重写来进行会话跟踪。
  • 从跨域名上比较
    • Cookie可以设置domain属性来实现跨域名
    • Session只在当前的域名内有效,不可夸域名

Servlet安全性问题

由于Servlet是单例的,当多个用户访问Servlet的时候,服务器会为每个用户创建一个线程当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题

原则:

  1. 如果一个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制synchronized (对象){}
  2. 如果一个变量不需要共享,则直接在 doGet() 或者 doPost()定义.这样不会存在线程安全问题

参考资料

JDBC

JDBC操作数据库的步骤 ?

  1. 注册数据库驱动。
  2. 建立数据库连接。
  3. 创建一个Statement。
  4. 执行SQL语句。
  5. 处理结果集。
  6. 关闭数据库连接

JDBC中的Statement 和PreparedStatement,CallableStatement的区别?

区别:

  • PreparedStatement是预编译的SQL语句,效率高于Statement。
  • PreparedStatement支持?操作符,相对于Statement更加灵活。
  • PreparedStatement可以防止SQL注入,安全性高于Statement。
  • CallableStatement适用于执行存储过程。

JDBC中大数据量的分页解决方法?

最好的办法是利用sql语句进行分页,这样每次查询出的结果集中就只包含某页的数据内容。

mysql语法:

SELECT *
FROM 表名
LIMIT [START], length;

说说数据库连接池工作原理和实现方案?

工作原理:

  • JAVA EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。

实现方案:连接池使用集合来进行装载,返回的Connection是原始Connection的代理,代理Connection的close方法,当调用close方法时,不是真正关连接,而是把它代理的Connection对象放回到连接池中,等待下一次重复利用。

Java中如何进行事务的处理?

Connection类中提供了4个事务处理方法:

  • setAutoCommit(Boolean autoCommit):设置是否自动提交事务,默认为自动提交,即为true,通过设置false禁止自动提交事务;
  • commit():提交事务;
  • rollback():回滚事务.
  • savepoint:保存点
  • 注意:savepoint不会结束当前事务,普通提交和回滚都会结束当前事务的

execute,executeQuery,executeUpdate的区别是什么?

  • Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true。如果结果不是ResultSet,比如insert或者update查询,它就会返回false。我们可以通过它的getResultSet方法来获取ResultSet,或者通过getUpdateCount()方法来获取更新的记录条数。

  • Statement的executeQuery(String query)接口用来执行select查询,并且返回ResultSet。即使查询不到记录返回的ResultSet也不会为null。我们通常使用executeQuery来执行查询语句,这样的话如果传进来的是insert或者update语句的话,它会抛出错误信息为 “executeQuery method can not be used for update”的java.util.SQLException。

  • Statement的executeUpdate(String query)方法用来执行insert或者update/delete(DML)语句,或者 什么也不返回DDL语句。返回值是int类型,如果是DML语句的话,它就是更新的条数,如果是DDL的话,就返回0。

  • 只有当你不确定是什么语句的时候才应该使用execute()方法,否则应该使用executeQuery或者executeUpdate方法。

  • JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?

常见的JDBC异常有哪些?

有以下这些:

  • java.sql.SQLException——这是JDBC异常的基类。
  • java.sql.BatchUpdateException——当批处理操作执行失败的时候可能会抛出这个异常。这取决于具体的JDBC驱动的实现,它也可能直接抛出基类异常java.sql.SQLException。
  • java.sql.SQLWarning——SQL操作出现的警告信息。
  • java.sql.DataTruncation——字段值由于某些非正常原因被截断了(不是因为超过对应字段类型的长度限制)。

JDBC中存在哪些不同类型的锁?

  • 乐观锁——只有当更新数据的时候才会锁定记录
  • 悲观锁——从查询到更新和提交整个过程都会对数据记录进行加锁。

什么是JDBC的最佳实践?

什么是JDBC的最佳实践?

  • 数据库资源是非常昂贵的,用完了应该尽快关闭它。Connection, Statement, ResultSet等JDBC对象都有close方法,调用它就好了。
  • 养成在代码中显式关闭掉ResultSet,Statement,Connection的习惯,如果你用的是连接池的话,连接用完后会放回池里,但是没有关闭的ResultSet和Statement就会造成资源泄漏了。
  • 在finally块中关闭资源,保证即便出了异常也能正常关闭。
  • 大量类似的查询应当使用批处理完成
  • 尽量使用PreparedStatement而不是Statement,以避免SQL注入,同时还能通过预编译和缓存机制提升执行的效率。
  • 如果你要将大量数据读入到ResultSet中,应该合理的设置fetchSize以便提升性能
  • 你用的数据库可能没有支持所有的隔离级别,用之前先仔细确认下。
  • 数据库隔离级别越高性能越差,确保你的数据库连接设置的隔离级别是最优的。
  • 如果在WEB程序中创建数据库连接,最好通过JNDI使用JDBC的数据源,这样可以对连接进行重用。
  • 如果你需要长时间对ResultSet进行操作的话,尽量使用离线的RowSet。

JDBC

过滤器与监听器

监听器有哪些作用和用法?

监听器有哪些作用和用法?

Java Web开发中的监听器(listener)就是application、session、request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件,如下所示:

  • ①ServletContextListener:对Servlet上下文的创建和销毁进行监听。
  • ②ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换。
  • ③HttpSessionListener:对Session的创建和销毁进行监听。
  • session超时(可以在web.xml中通过
  • /
  • 标签配置超时时间);
    • 通过调用session对象的invalidate()方 法使session失效。
    • 补 充:session的销毁有两种情况:
  • ④HttpSessionAttributeListener:对Session对象中属性的添加、删除和替换进行监听。
  • ⑤ServletRequestListener:对请求对象的初始化和销毁进行监听。
  • ⑥ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听。

常见的监听器用途主要包括:网站在线人数技术、监听用户的行为(管理员踢人)

过滤器有哪些作用和用法?

过滤器有哪些作用和用法?

Java Web开发中的过滤器(filter)是从Servlet 2.3规范开始增加的功能,并在Servlet 2.4规范中得到增强。对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过 滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联。如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改 变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同样会将响应先转发给过滤器,再过滤器中, 你可以对响应的内容进行转换,然后再将响应发送到客户端。

常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件、对XML的输出应用XSLT等

和过滤器相关的接口主要有:Filter、FilterConfig、FilterChain

web.xml 的作用?

web.xml 的作用?

答:用于配置Web应用的相关信息,如:监听器(listener)、过滤器(filter)、 Servlet、相关参数、会话超时时间、安全验证方式、错误页面等。例如:

①配置Spring上下文加载监听器加载Spring配置文件:

<context-param>  
   <param-name>contextConfigLocation</param-name>  
  <param-value>classpath:applicationContext.xml</param-value>  
</context-param>  

<listener>  
   <listener-class>  
     org.springframework.web.context.ContextLoaderListener  
   </listener-class>  
</listener>  

②配置Spring的OpenSessionInView过滤器来解决延迟加载和Hibernate会话关闭的矛盾:

<filter>  
  <filter-name>openSessionInView</filter-name>  
  <filter-class>  
     org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  
  </filter-class>  
</filter>  

<filter-mapping>  
  <filter-name>openSessionInView</filter-name>  
  <url-pattern>/*</url-pattern>  
</filter-mapping>  

③配置会话超时时间为10分钟:

<session-config>  
  <session-timeout>10</session-timeout>  
</session-config>  

④配置404和Exception的错误页面:

[html] view plaincopy在CODE上查看代码片派生到我的代码片 
<error-page>  
  <error-code>404</error-code>  
  <location>/error.jsp</location>  
</error-page>  

<error-page>  
  <exception-type>java.lang.Exception</exception-type>  
  <location>/error.jsp</location>  
</error-page>  

⑤配置安全认证方式:

<security-constraint>  
  <web-resource-collection>  
    <web-resource-name>ProtectedArea</web-resource-name>  
    <url-pattern>/admin/*</url-pattern>  
    <http-method>GET</http-method>  
    <http-method>POST</http-method>  
  </web-resource-collection>  
  <auth-constraint>  
    <role-name>admin</role-name>  
  </auth-constraint>  
</security-constraint>  

<login-config>  
  <auth-method>BASIC</auth-method>  
</login-config>  

<security-role>  
  <role-name>admin</role-name>  
</security-role>  

【补 充1】从Servlet 3开始,可以不用在web.xml中部署Servlet(小服务)、Filter(过滤器)、Listener(监听器)等Web组件,Servlet 3提供了基于注解的部署方式,可以分别使用@WebServlet、@WebFilter、@WebListener三个部署小服务、过滤器、监听器。

【补充2】如果Web提供了有价值的商业信息或者是敏感数据,那么站点的安全性就是必须考虑的问题。安全认证是实现安全性的重要手段,认证就是要解决“Are you who you say you are?”的问题。认证的方式非常多,简单说来可以分为三类:

A.What you know? --口令

B.What you have? --数字证书(U盾、密保卡)

C.Who you are? – 指纹识别、虹膜识别

在Tomcat中可以通过建立安全套接字层(Secure Socket Layer, SSL)以及通过基本验证或表单验证来实现对安全性的支持。

Servlet 3中的异步处理指的是什么?

Servlet 3中的异步处理指的是什么?

答: 在Servlet 3中引入了一项新的技术可以让Servlet异步处理请求。有人可能会质疑,既然都有多线程了,还需要异步处理请求吗?答案是肯定的,因为如果一个任务处 理时间相当长,那么Servlet或Filter会一直占用着请求处理线程直到任务结束,随着并发用户的增加,容器将会遭遇线程超出的风险,这这种情况下 很多的请求将会被堆积起来而后续的请求可能会遭遇拒绝服务,直到有资源可以处理请求为止。异步特性可以帮助应用节省容器中的线程,特别适合执行时间长而且 用户需要得到结果的任务,如果用户不需要得到结果则直接将一个Runnable对象交给Executor(如果不清楚请查看前文关于多线程和线程池的部 分)并立即返回即可

开启异步处理代码:

@WebServlet(urlPatterns = {"/async"}, asyncSupported = true)  
public class AsyncServlet extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    @Override  
    public void doGet(HttpServletRequest req, HttpServletResponse resp)   
            throws ServletException, IOException {  
        // 开启Tomcat异步Servlet支持  
        req.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);  

        final AsyncContext ctx = req.startAsync();  // 启动异步处理的上下文  
        // ctx.setTimeout(30000);  
        ctx.start(new Runnable() {  

            @Override  
            public void run() {  
                // 在此处添加异步处理的代码  

                ctx.complete();  
            }  
        });  
    }  
}  

JSON

什么是JSON

JSON:JavaScript Object Notation 【JavaScript 对象表示法】

JSON 是存储和交换文本信息的语法。类似 XML。

JSON采用完全独立于任何程序语言的文本格式,使JSON成为理想的数据交换语言S

为什么需要JSON

提到JSON,我们就应该和XML来进行对比。XML也是一种存储和交换文本信息的手段。那么JSON好在哪里呢??

JSON 比 XML 更小、更快,更易解析

  • javaScript原生支持JSON,解析速度会很快
  • XML解析成DOM对象的时候,浏览器【IE和fireFox】会有差异
  • 使用JSON会更简单

img更加容易创建JavaScript对象**

var p = {'city':['北京','上海','广州','深圳']};
for(var i=0;i<p.city.length;i++){
    document.write(p.city[i]+"<br/>");
}

JSON语法

客户端与服务端的交互数据无非就是两种

  • 数组
  • 对象

于是乎,JSON所表示的数据要么就是对象,要么就是数组

JSON语法是javaScript语法的子集,javaScript用[]中括号来表示数组,用{}大括号来表示对象,JSON亦是如此

JSON数组:

var employees = [
{ "firstName":"Bill" , "lastName":"Gates" },
{ "firstName":"George" , "lastName":"Bush" },
{ "firstName":"Thomas" , "lastName": "Carter" }
];

JSON对象

var obj = {

    age: 20,
    str: "zhongfucheng",
    method: function () {
        alert("我爱学习");
    }

};

当然啦,数组可以包含对象,在对象中也可以包含数组


解析JSON

javaScript原生支持JSON的,我们可以使用eval()函数来解析JSON,把JSON文本数据转换成一个JavaScript对象。

function test() {
    //在写JOSN的时候,记得把带上逗号
    var txt = "{a:123," +
            "b:'zhongfucheng'}";

    //使用eval解析JSON字符串,需要增添()
    var aa = eval("(" + txt + ")");
    alert(aa);

}

效果

img

不用框架时将JavaBean转成JSON

  • 使用Strus2的时候,Struts2自带了组件能够让JavaBean对象、集合转成是JSON,不用我们自己拼接…这是非常方便的。
  • 使用SpringMVC的时候,SpringMVC也支持将JavaBean转成JSON

但是,我们不一定使用框架来做开发呀。因此,我们还得学习使用第三方库来将JavaBean对象、集合转成JSON

导入开发包

  • commons-io-2.0.1.jar
  • commons-lang-2.5.jar
  • commons-collections-3.1.jar
  • commons-beanutils-1.7.0.jar
  • ezmorph-1.0.3.jar
  • json-lib-2.1-jdk15.jar

事例代码

package cn.itcast.javaee.js.bean2json;

import net.sf.json.JSONArray;

import java.util.*;

/**
 * 使用第三方工具,将JavaBean对象/List或Set或Map对象转成JSON 
 * @author AdminTC
 */
public class TestBean2Json {
    private static void javabean2json() {
        City city = new City(1,"广州");
        JSONArray jSONArray = JSONArray.fromObject(city);
        String jsonJAVA = jSONArray.toString();
        System.out.println(jsonJAVA);
        //[{"id":1,"name":"广州"}]
    }
    private static void list2json() {
        List<City> cityList = new ArrayList<City>();
        cityList.add(new City(1,"广州"));
        cityList.add(new City(2,"珠海"));
        JSONArray jSONArray = JSONArray.fromObject(cityList);
        String jsonJAVA = jSONArray.toString();
        System.out.println(jsonJAVA);
        //[{"id":1,"name":"广州"},{"id":2,"name":"珠海"}]
    }
    private static void set2json() {
        Set<City> citySet = new LinkedHashSet<City>();
        citySet.add(new City(1,"广州"));
        citySet.add(new City(2,"珠海"));
        JSONArray jSONArray = JSONArray.fromObject(citySet);
        String jsonJAVA = jSONArray.toString();
        System.out.println(jsonJAVA);
        //[{"id":1,"name":"广州"},{"id":2,"name":"珠海"}]
    }
    private static void javabeanlist2json() {
        List<City> cityList = new ArrayList<City>();
        cityList.add(new City(1,"中山"));
        cityList.add(new City(2,"佛山"));
        Province province = new Province(1,"广东",cityList);

        JSONArray jSONArray = JSONArray.fromObject(province);
        String jsonJAVA = jSONArray.toString();
        System.out.println(jsonJAVA);
        /*
          [
             {
              "id":1,
              "name":"广东"
              "cityList":[{"id":1,"name":"中山"},{"id":2,"name":"佛山"}],
             }
          ]
          */
    }
    private static void map2json() {

        List<City> cityList = new ArrayList<City>();
        cityList.add(new City(1,"中山"));
        cityList.add(new City(2,"佛山"));

        Map<String,Object> map = new LinkedHashMap<String,Object>();
        map.put("total",cityList.size());//表示集合的长度
        map.put("rows",cityList);//rows表示集合

        JSONArray jSONArray = JSONArray.fromObject(map);
        String jsonJAVA = jSONArray.toString();
        System.out.println(jsonJAVA);
        //[{"total":2,"rows":[{"id":1,"name":"中山"},{"id":2,"name":"佛山"}]}]

        jsonJAVA = jsonJAVA.substring(1,jsonJAVA.length()-1);
        System.out.println(jsonJAVA);
    }

}

把要解析成JSON 的javaBena对象、集合放进下面这段代码即可!

JSONArray jSONArray = JSONArray.fromObject(map);

无论放进去什么,返回的都是数组

在网站前台和后台数据传输,采用json的格式,你觉得这种格式有什么优缺点?

json的缺点是有数据中有很多重复项,通过Zip压缩能减少重复项,Tomcat在处理的时候会自动判断进行压缩。

总结

img

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值