Contenu connexe Similaire à JavaOne Shanghai 2013 - Servlet 3.1 (JSR 340) (20) JavaOne Shanghai 2013 - Servlet 3.1 (JSR 340)2. Servlet 3.1 (JSR 340) 有什麼新
功能?
Shing Wai Chan (陳成威)
Servlet 3.1 Specification Lead
java.net/blog/swchan2
Session ID: CON1387
3. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.3
以下内容旨在概述产品的总体发展方向。该内容仅供参考,不可纳入任何合同。其
内容不构成提供任何材料、代码或功能的承诺,并且不应该作为制定购买决策的依
据。此处所述有关 Oracle 产品的任何特性或功能的开发、发布以及相应的日程安
排均由 Oracle 自行决定。
4. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.4
议题
§ Servlet 3.1 概述
§ Non-blocking IO
§ 协议升级
§ 安全性增强
§ 杂项功能
§ 资源
5. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.5
Servlet 3.1 概述
§ Java EE 7 的特性
§ Servlet 3.0的升级
§ 可扩展性
– 添加 Non-blocking IO API
§ 支持新技术,利用HTTP协议的初始握手
– 支持一般的协议升级机制,例如 WebSocket
§ 安全性增强
6. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.6
议题
§ Servlet 3.1 概述
§ Non-blocking IO
§ 协议升级
§ 安全性增强
§ 杂项功能
§ 资源
7. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.7
Non-blocking IO
public class TestServlet extends HttpServlet
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
ServletInputStream input =
request.getInputStream();
byte[] b = new byte[1024];
int len = -1;
while ((len = input.read(b)) != -1) {
…
}
}
}
傳統 IO 示範
8. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.8
Non Blocking IO
§ 添加兩个新接口: ReadListener, WriteListener
§ 在 ServletInputStream 和 ServletOutputStream 中添加方法
§ 只可在非同步 (asynchronous) 和协议升级時使用
概述
9. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.9
Non-blocking IO
public interface ReadListener extends EventListener {
public void onDataAvailable() throws IOException;
public void onAllDataRead() throws IOException;
public void onError(Throwable t);
}
javax.servlet.ReadListener
10. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.10
Non-blocking IO
public interface WriteListener extends EventListener {
public void onWritePossible() throws IOException;
public void onError(Throwable t);
}
javax.servlet.WriteListener
11. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.11
Non-blocking IO
§ javax.servlet.ServletInputStream
– public abstract boolean isFinished()
– public abstract boolean isReady()
– public abstract void setReadListener(ReadListener
listener)
§ javax.servlet.ServletOutputStream
– public abstract boolean isReady()
– public abstract setWriteListener(WriteListener
listener)
ServletInputStream, ServletOutputStream
12. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.12
Non-blocking IO
public class TestServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse
res) throws IOException, ServletException {
AsyncContext ac = req.startAsync();
…
ServletInputStream input = req.getInputStream();
ReadListener readListener = new ReadListenerImpl(input, output,
ac);
input.setReadListener(readListener);
}
}
示範
13. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.13
Non-blocking IO
public class ReadListenerImpl implements ReadListener {
…
public void onDataAvailable() throws IOException {
…
int len = -1;
byte b[] = new byte[1024];
while ((len = input.read(b)) != -1) {
…
}
}
public void onAllDataRead() throws IOException {
…
}
public void onError(final Throwable t) {
…
}
}
示範 (续):测验
14. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.14
Non-blocking IO
public class ReadListenerImpl implements ReadListener {
…
public void onDataAvailable() throws IOException {
…
int len = -1;
byte b[] = new byte[1024];
while (input.isReady() && (len = input.read(b)) != -1) {
…
}
}
public void onAllDataRead() throws IOException {
ac.complete();
}
public void onError(final Throwable t) {
…
}
}
示範 (续):测验解答
15. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.15
Non-blocking IO
public class TestServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse
res) throws IOException, ServletException {
AsyncContext ac = req.startAsync();
…
ServletOutputStream output = req.getOutputStream();
WriteListener writeListener = new WriteListenerImpl(output,
ac);
output.setWriteListener(writeListener);
}
}
示範 2
16. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.16
Non-blocking IO
public class WriteListenerImpl implements WriteListener {
…
public void onWritePossible() throws IOException {
…
int len = -1;
byte b[] = new byte[1024];
while (output.isReady()) {
…
}
…
}
public void onError(final Throwable t) {
…
}
}
示範 2 (续)
17. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.17
议题
§ Servlet 3.1 概述
§ Non-blocking IO
§ 协议升级
§ 安全性增强
§ 杂项功能
§ 资源
18. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.18
协议升级
§ HTTP 1.1 (RFC 2616)
§ Connection
§ 过渡到一些其他的,不兼容的协议
– For examples, IRC/6.9, Web Socket
HTTP Upgrade
19. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.19
协议升级
§ 协议: IETF
§ API: W3C
§ 双向,全双工 / TCP
示例: WebSocket
20. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.20
Client
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key:
dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat,
superchat
Sec-WebSocket-Version: 13
协议升级
Server
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept:
s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
WebSocket 示例
21. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.21
协议升级
§ 添加方法在 HttpServletRequest 中
§ 添加两个新接口
– javax.servlet.http.HttpUpgradeHandler
– javax.servlet.http.WebConnection
§ 在升级中,可以使用 non-blocking IO API
概述
22. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.22
协议升级
§ 新接口 javax.servlet.http.HttpUpgradeHandler
– void init(WebConnection wc)
– void destroy()
§ 新接口 javax.servlet.http.WebConnection extends
AutoClosable
– ServletInputStream getInputStream() throws IOException
– ServletOutputStream getOutputStream() throws
IOException
HttpUpgradeHandler, WebConnection
23. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.23
协议升级
§ 添加方法在 HttpServletRequest
– <T extends HttpUpgradeHandler>
T upgrade(Class<T> handlerClass)
throws IOException, ServletException
HttpServletRequest
24. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.24
协议升级
HttpServlet /
Filter
req.upgrade(…)
init
destroy
HTTP Request
升级协议的
请求 / 响应
HttpUpgradeHandler
25. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.25
协议升级
public class UpgradeServlet extends HttpServlet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
…
if (decideToUpgrade) {
EchoHttpUpgradeHandler handler =
request.upgrade(EchoHttpUpgradeHandler.class);
…
}
}
示範
26. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.26
协议升级
public class EchoProtocolHandler implements HttpUpgradeHandler {
public void init(WebConnection wc) {
try {
ServletInputStream input = wc.getInputStream();
ServletOutputStream output = wc.getOutputStream();
ReadListener readListener = …;
input.setReadListener(readListener);
…
}
public void destroy() {
…
}
}
示範 (续)
27. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.27
协议升级
TyrusServletFilter
req.upgrade(…)
init
destroy
HTTP Request
WebSocket
的请求 / 响
应
TyrusHttpUpgradeHandler
示範 2: JSR356,Java API for WebSocket 的参考实现
29. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.29
Agenda
§ Servlet 3.1 概述
§ Non-blocking IO
§ 协议升级
§ 安全性增强
§ 杂项功能
§ 资源
30. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.30
安全性增强
§ 黑客的电子邮件或网⻚页
– http://abank.com?SID=ABCDEFGHIJ
§ 身份验证后改变 Session id
– 添加在接口 HttpServletRequest
§ public String changeSessionId()
– 新接口 javax.servlet.http.HttpSessionIdListener
§ void sessionIdChanged(HttpSessionEvent se, String
oldSessionId)
Session 固定攻擊
31. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.31
安全性增强
User Group Role /foo (“*”) /bar (“admin”)
Alice manager admin
Bob staff staff
Carol contractor
任何通過身份驗證的用戶
测验
32. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.32
安全性增强
§ 角色 “*” 是指任何定义的角色
任何通過身份驗證的用戶
测验解答
User Group Role /foo (“*”) /bar (“admin”)
Alice manager admin ok ok
Bob staff staff ok deny
Carol contractor deny deny
33. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.33
安全性增强
§ 角色 “**”,任何通過身份驗證的用戶
§ 例如,
– @WebServlet(“/foo”)
@ServletSecurity(@HttpConstraint(rolesAllowed={“**”}))
任何通過身份驗證的用戶
34. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.34
安全性增强
§ deny-uncovered-http-methods: web.xml 中的元素
§ 示例,
– <web-app …>
" "…" " " ""
" "<deny-uncovered-http-methods/> " ""
" "<security-constraint>
" " "<web-resource-collection>
" " " "<web-resource-name>protected</web-resource-name>
" " " "<url-pattern>/*</url-pattern>
" " " "<http-method>GET</http-method>
" " "</web-resource-collection>
" " "<auth-constraint>
" " " "<role-name>manager</role-name>
" " "</auth-constraint>
" "</security-constraint>
</web-app>"
deny-uncovered-http-methods
35. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.35
安全性增强
§ 澄清 run-as 的有效範圍
– Servlet#init, Servlet#destroy
Run as
36. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.36
议题
§ Servlet 3.1概述
§ Non-blocking IO
§ 协议升级
§ 安全性增强
§ 杂项功能
§ 资源
37. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.37
杂项功能
§ ServletResponse#reset
– 清除 HTTP headers, status code, 缓冲区中的数据
§ ServletResponse#setCharacterEncoding
– 设置发送到客户端响应的字符编码(MIME字符集),例如,转换为UTF-8
– …
ServletResponse#reset 和 #setCharacterEncoding
Servlet 3.0
38. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.38
杂项功能
public class TestServlet extends HttpServlet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html");
response.setCharacterEncoding("ISO-8859-1");
PrintWriter writer = response.getWriter();
…
response.reset();
response.setContentType("text/plain");
response.setCharacterEncoding("Big5");
response.getOutputStream().println("Done");
}
}
ServletResponse#reset 和 setCharacterEncoding (续)
Servlet 3.0 测验
39. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.39
杂项功能
public class TestServlet extends HttpServlet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html");
response.setCharacterEncoding("ISO-8859-1");
PrintWriter writer = response.getWriter();
…
response.reset();
response.setContentType("text/plain");
response.setCharacterEncoding("Big5"); // no effect
response.getOutputStream().println("Done"); //
IllegalStateException
}
}
ServletResponse#reset 和 setCharacterEncoding (续 2)
Servlet 3.0 测验解答
40. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.40
杂项功能
§ ServletResponse#reset 后的字符编码设置
– 只有 #getServletOutputStream 或 #getWriter
– 在调用 #getWriter 后,#setCharacterEncoding 没有任何效果
– Servlet 3.0
§ #reset 清除 HTTP headers, status code, 缓冲区中的数据
– Servlet 3.1
§ #reset清除
– HTTP headers, status code, 缓冲区中的数据
– 调用 #getServletOutputStream 或 #getWriter 的状态
ServletResponse#reset 和 #setCharacterEncoding (续 3)
41. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.41
Miscellaneous
public class TestServlet extends HttpServlet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html");
response.setCharacterEncoding("ISO-8859-1");
PrintWriter writer = response.getWriter();
…
response.reset();
response.setContentType("text/plain");
response.setCharacterEncoding("Big5"); // set Big5 encoding
response.getOutputStream().println("Done"); // print
}
}
ServletResponse#reset 和 #setCharacterEncoding (续 4)
示例
42. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.42
杂项功能
§ HttpServletResponse.sendRedirect
– a.jsp
– /b/a.jsp
– http://anotherhost.com/b/a.jsp
– //anotherhost.com/b/a.jsp (网络路径参考)
相对协议的URL
43. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.43
杂项功能
§ 澄清 HttpServletRequest#getPart, #getParts 在没有multi-part 配置时
– 抛出 IllegalStateException
§ 添加方法
javax.servlet.http.Part#getSubmittedFileName()
Multi-part
44. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.44
杂项功能
§ 有关 ServletContainerInitiailizer 的澄清
– 独立于 metadata-complete
– 每一个Web应用程序有一实例
ServletContainerInitializer
45. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.45
杂项功能
§ ServletRequestWrapper#isWrapperFor(Class<?> c)
§ ServletResponseWrapper#isWrapperFor(Class<?> c)
§ HandlesTypes#value 返回 Class<?>[ ]
Generics
46. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.46
杂项功能
§ 添加方法 ServletContext#getVirtualServerName()
§ 添加方法 ServletRequest#getContentLengthLong()
§ 添加方法 ServletResponse#setContentLengthLong(long
len)
其他
47. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.47
Agenda
§ Servlet 3.1 概述
§ Non-blocking IO
§ 协议升级
§ 安全性增强
§ 杂项功能
§ 资源
48. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.48
资源
§ 规范和 API 文档
– http://jcp.org/en/jsr/detail?id=340
– http://servlet-spec.java.net
§ GlassFish 4.0
– http://glassfish.java.net
– webtier@glassfish.java.net
§ 博客
– http://www.java.net/blog/swchan2
49. Copyright © 2013 Oracle and/or its affiliates. All rights reserved.49
Graphic Section Divider