UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

275 lines (260 loc) 36 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>Talking to Web Applications</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Talking to Web Applications"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-14-SECT-3"/>Talking to Web Applications</h1></div></div></div><p>Web browsers are the universal clients for web applications. They retrieve documents for display and serve as a user interface, primarily through the use of HTML, JavaScript, and linked documents. In this section, we‘ll show how to write client-side Java code that uses HTTP through the <a id="I_indexterm14_id774305" class="indexterm"/><code class="literal">URL</code> class to work with web applications directly using <a id="I_indexterm14_id774316" class="indexterm"/><code class="literal">GET</code> and <a id="I_indexterm14_id774327" class="indexterm"/><code class="literal">POST</code> operations to retrieve and send data. Later in this chapter, we’ll begin a discussion of web services, which marry HTTP with XML to enable cross-platform application-to-application communications using web standards.</p><p>There are many reasons an application might want to communicate via HTTP. For example, compatibility with another browser-based application might be important, or you might need to gain access to a server through a firewall where direct socket connections (and RMI) are problematic. HTTP is the lingua franca of the Net, and despite its limitations (or more likely because of its simplicity), it has rapidly become one of the most widely supported protocols in the world. As for using Java on the client side, all the other reasons you would write a client-side GUI or non-GUI application (as opposed to a pure web/HTML-based application) also present themselves. A client-side GUI can perform sophisticated presentation and validation while, with the techniques presented here, still using web-enabled services over the network.</p><p>The primary task we discuss here is sending data to the server, specifically HTML form-encoded data. In a web browser, the name/value pairs of HTML form fields are encoded in a special format and sent to the server using one of two methods. The first method, using the HTTP <code class="literal">GET</code> command, encodes the user’s input into the URL and requests the corresponding document. The server recognizes that the first part of the URL refers to a program and invokes it, passing along the information encoded in the URL as a parameter. The second method uses the HTTP <code class="literal">POST</code> command to ask the server to accept the encoded data and pass it to a web application as a stream. In Java, we can create a URL that refers to a server-side program and request or send it data using the <code class="literal">GET</code> and <code class="literal">POST</code> methods. (In <a class="xref" href="ch15.html" title="Chapter 15. Web Applications and Web Services">Chapter 15</a>, we’ll see how to build web applications that implement the other side of this conversation.)</p><div class="sect2" title="Using the GET Method"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-14-SECT-3.1"/>Using the GET Method</h2></div></div></div><p><a id="I_indexterm14_id774397" class="indexterm"/> <a id="I_indexterm14_id774403" class="indexterm"/>Using the <code class="literal">GET</code> method of encoding data in a URL is pretty easy. All we have to do is create a URL pointing to a server program and use a simple convention to tack on the encoded name/value pairs that make up our data. For example, the following code snippet opens a URL to an old-school CGI program called <span class="emphasis"><em>login.cgi</em></span> on the server <span class="emphasis"><em>myhost</em></span> and passes it two name/value pairs. It then prints whatever text the CGI sends back:</p><a id="I_14_tt905"/><pre class="programlisting"><code class="n">URL</code> <code class="n">url</code> <code class="o">=</code> <code class="k">new</code> <code class="n">URL</code><code class="o">(</code> <code class="c1">// this string should be URL-encoded</code> <code class="s">"http://myhost/cgi-bin/login.cgi?Name=Pat&amp;Password=foobar"</code><code class="o">);</code> <code class="n">BufferedReader</code> <code class="n">bin</code> <code class="o">=</code> <code class="k">new</code> <code class="n">BufferedReader</code> <code class="o">(</code> <code class="k">new</code> <code class="nf">InputStreamReader</code><code class="o">(</code> <code class="n">url</code><code class="o">.</code><code class="na">openStream</code><code class="o">()</code> <code class="o">));</code> <code class="n">String</code> <code class="n">line</code><code class="o">;</code> <code class="k">while</code> <code class="o">(</code> <code class="o">(</code><code class="n">line</code> <code class="o">=</code> <code class="n">bin</code><code class="o">.</code><code class="na">readLine</code><code class="o">())</code> <code class="o">!=</code> <code class="kc">null</code> <code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">line</code> <code class="o">);</code> <code class="o">}</code></pre><p>To form the URL with parameters, we start with the base URL of <span class="emphasis"><em>login.cgi</em></span>; we add a question mark (<code class="literal">?</code>), which marks the beginning of the parameter data, followed by the first name/value pair. We can add as many pairs as we want, separated by ampersand (<code class="literal">&amp;</code>) characters. The rest of our code simply opens the stream and reads back the response from the server. Remember that creating a URL doesn’t actually open the connection. In this case, the URL connection was made implicitly when we called <code class="literal">openStream()</code>. Although we are assuming here that our server sends back text, it could send anything.</p><p>It’s important to point out that we have skipped a step here. This example works because our name/value pairs happen to be simple text. If any “nonprintable” or special characters (including <a id="I_indexterm14_id774480" class="indexterm"/><a id="I_indexterm14_id774487" class="indexterm"/><code class="literal">?</code> or <code class="literal">&amp;</code>) are in the pairs, they must be encoded first. The <a id="I_indexterm14_id774506" class="indexterm"/><code class="literal">java.net.</code><code class="literal">URL</code><code class="literal">Encoder</code><code class="literal"/> class provides a utility for encoding the data. We’ll show how to use it in the next example.</p><p>Another important thing is that although this small example sends a password field, you should never send sensitive data using this simplistic approach. The data in this example is sent in clear text across the network (it is not encrypted). And in this case, the password field would appear anywhere the URL is printed as well (e.g., server logs and bookmarks). We’ll talk about secure web communications later in this chapter and when we discuss writing web applications using servlets in <a class="xref" href="ch15.html" title="Chapter 15. Web Applications and Web Services">Chapter 15</a>.</p></div><div class="sect2" title="Using the POST Method"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-14-SECT-3.2"/>Using the POST Method</h2></div></div></div><p><a id="idx10813" class="indexterm"/> <a id="idx10830" class="indexterm"/>Here’s a small application that acts like an HTML form. It gathers data from two text fields—<code class="literal">name</code> and <code class="literal">password</code>—and posts the data to a specified URL using the HTTP <code class="literal">POST</code> method. This Swing-based client application works with a server-side web-based application, just like a web browser.</p><p>Here’s the code:</p><a id="I_14_tt906"/><pre class="programlisting"><code class="c1">//file: Post.java</code> <code class="kn">import</code> <code class="nn">java.net.*</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">java.io.*</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">java.awt.*</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">java.awt.event.*</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">javax.swing.*</code><code class="o">;</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">Post</code> <code class="kd">extends</code> <code class="n">JPanel</code> <code class="kd">implements</code> <code class="n">ActionListener</code> <code class="o">{</code> <code class="n">JTextField</code> <code class="n">nameField</code><code class="o">,</code> <code class="n">passwordField</code><code class="o">;</code> <code class="n">String</code> <code class="n">postURL</code><code class="o">;</code> <code class="n">GridBagConstraints</code> <code class="n">constraints</code> <code class="o">=</code> <code class="k">new</code> <code class="n">GridBagConstraints</code><code class="o">(</code> <code class="o">);</code> <code class="kt">void</code> <code class="nf">addGB</code><code class="o">(</code> <code class="n">Component</code> <code class="n">component</code><code class="o">,</code> <code class="kt">int</code> <code class="n">x</code><code class="o">,</code> <code class="kt">int</code> <code class="n">y</code> <code class="o">)</code> <code class="o">{</code> <code class="n">constraints</code><code class="o">.</code><code class="na">gridx</code> <code class="o">=</code> <code class="n">x</code><code class="o">;</code> <code class="n">constraints</code><code class="o">.</code><code class="na">gridy</code> <code class="o">=</code> <code class="n">y</code><code class="o">;</code> <code class="n">add</code> <code class="o">(</code> <code class="n">component</code><code class="o">,</code> <code class="n">constraints</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">public</code> <code class="nf">Post</code><code class="o">(</code> <code class="n">String</code> <code class="n">postURL</code> <code class="o">)</code> <code class="o">{</code> <code class="k">this</code><code class="o">.</code><code class="na">postURL</code> <code class="o">=</code> <code class="n">postURL</code><code class="o">;</code> <code class="n">setBorder</code><code class="o">(</code><code class="n">BorderFactory</code><code class="o">.</code><code class="na">createEmptyBorder</code><code class="o">(</code><code class="mi">5</code><code class="o">,</code> <code class="mi">10</code><code class="o">,</code> <code class="mi">5</code><code class="o">,</code> <code class="mi">5</code><code class="o">));</code> <code class="n">JButton</code> <code class="n">postButton</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JButton</code><code class="o">(</code><code class="s">"Post"</code><code class="o">);</code> <code class="n">postButton</code><code class="o">.</code><code class="na">addActionListener</code><code class="o">(</code> <code class="k">this</code> <code class="o">);</code> <code class="n">setLayout</code><code class="o">(</code> <code class="k">new</code> <code class="n">GridBagLayout</code><code class="o">(</code> <code class="o">)</code> <code class="o">);</code> <code class="n">constraints</code><code class="o">.</code><code class="na">fill</code> <code class="o">=</code> <code class="n">GridBagConstraints</code><code class="o">.</code><code class="na">HORIZONTAL</code><code class="o">;</code> <code class="n">addGB</code><code class="o">(</code> <code class="k">new</code> <code class="n">JLabel</code><code class="o">(</code><code class="s">"Name "</code><code class="o">,</code> <code class="n">JLabel</code><code class="o">.</code><code class="na">TRAILING</code><code class="o">),</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">0</code> <code class="o">);</code> <code class="n">addGB</code><code class="o">(</code> <code class="n">nameField</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JTextField</code><code class="o">(</code><code class="mi">20</code><code class="o">),</code> <code class="mi">1</code><code class="o">,</code> <code class="mi">0</code> <code class="o">);</code> <code class="n">addGB</code><code class="o">(</code> <code class="k">new</code> <code class="n">JLabel</code><code class="o">(</code><code class="s">"Password "</code><code class="o">,</code> <code class="n">JLabel</code><code class="o">.</code><code class="na">TRAILING</code><code class="o">),</code> <code class="mi">0</code><code class="o">,</code> <code class="mi">1</code> <code class="o">);</code> <code class="n">addGB</code><code class="o">(</code> <code class="n">passwordField</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JPasswordField</code><code class="o">(</code><code class="mi">20</code><code class="o">),</code> <code class="mi">1</code><code class="o">,</code> <code class="mi">1</code> <code class="o">);</code> <code class="n">constraints</code><code class="o">.</code><code class="na">fill</code> <code class="o">=</code> <code class="n">GridBagConstraints</code><code class="o">.</code><code class="na">NONE</code><code class="o">;</code> <code class="n">constraints</code><code class="o">.</code><code class="na">gridwidth</code> <code class="o">=</code> <code class="mi">2</code><code class="o">;</code> <code class="n">constraints</code><code class="o">.</code><code class="na">anchor</code> <code class="o">=</code> <code class="n">GridBagConstraints</code><code class="o">.</code><code class="na">EAST</code><code class="o">;</code> <code class="n">addGB</code><code class="o">(</code> <code class="n">postButton</code><code class="o">,</code> <code class="mi">1</code><code class="o">,</code> <code class="mi">2</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">actionPerformed</code><code class="o">(</code><code class="n">ActionEvent</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code> <code class="n">postData</code><code class="o">(</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">protected</code> <code class="kt">void</code> <code class="nf">postData</code><code class="o">(</code> <code class="o">)</code> <code class="o">{</code> <code class="n">StringBuffer</code> <code class="n">sb</code> <code class="o">=</code> <code class="k">new</code> <code class="n">StringBuffer</code><code class="o">(</code> <code class="o">);</code> <code class="n">sb</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="n">URLEncoder</code><code class="o">.</code><code class="na">encode</code><code class="o">(</code><code class="s">"Name"</code><code class="o">)</code> <code class="o">+</code> <code class="s">"="</code> <code class="o">);</code> <code class="n">sb</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="n">URLEncoder</code><code class="o">.</code><code class="na">encode</code><code class="o">(</code><code class="n">nameField</code><code class="o">.</code><code class="na">getText</code><code class="o">(</code> <code class="o">))</code> <code class="o">);</code> <code class="n">sb</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="s">"&amp;"</code> <code class="o">+</code> <code class="n">URLEncoder</code><code class="o">.</code><code class="na">encode</code><code class="o">(</code><code class="s">"Password"</code><code class="o">)</code> <code class="o">+</code> <code class="s">"="</code> <code class="o">);</code> <code class="n">sb</code><code class="o">.</code><code class="na">append</code><code class="o">(</code> <code class="n">URLEncoder</code><code class="o">.</code><code class="na">encode</code><code class="o">(</code><code class="n">passwordField</code><code class="o">.</code><code class="na">getText</code><code class="o">(</code> <code class="o">))</code> <code class="o">);</code> <code class="n">String</code> <code class="n">formData</code> <code class="o">=</code> <code class="n">sb</code><code class="o">.</code><code class="na">toString</code><code class="o">(</code> <code class="o">);</code> <code class="k">try</code> <code class="o">{</code> <code class="n">URL</code> <code class="n">url</code> <code class="o">=</code> <code class="k">new</code> <code class="n">URL</code><code class="o">(</code> <code class="n">postURL</code> <code class="o">);</code> <code class="n">HttpURLConnection</code> <code class="n">urlcon</code> <code class="o">=</code> <code class="o">(</code><code class="n">HttpURLConnection</code><code class="o">)</code> <code class="n">url</code><code class="o">.</code><code class="na">openConnection</code><code class="o">(</code> <code class="o">);</code> <code class="n">urlcon</code><code class="o">.</code><code class="na">setRequestMethod</code><code class="o">(</code><code class="s">"POST"</code><code class="o">);</code> <code class="n">urlcon</code><code class="o">.</code><code class="na">setRequestProperty</code><code class="o">(</code><code class="s">"Content-type"</code><code class="o">,</code> <code class="s">"application/x-www-form-urlencoded"</code><code class="o">);</code> <code class="n">urlcon</code><code class="o">.</code><code class="na">setDoOutput</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code> <code class="n">urlcon</code><code class="o">.</code><code class="na">setDoInput</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code> <code class="n">PrintWriter</code> <code class="n">pout</code> <code class="o">=</code> <code class="k">new</code> <code class="n">PrintWriter</code><code class="o">(</code> <code class="k">new</code> <code class="n">OutputStreamWriter</code><code class="o">(</code> <code class="n">urlcon</code><code class="o">.</code><code class="na">getOutputStream</code><code class="o">(</code> <code class="o">),</code> <code class="s">"8859_1"</code><code class="o">),</code> <code class="kc">true</code> <code class="o">);</code> <code class="n">pout</code><code class="o">.</code><code class="na">print</code><code class="o">(</code> <code class="n">formData</code> <code class="o">);</code> <code class="n">pout</code><code class="o">.</code><code class="na">flush</code><code class="o">(</code> <code class="o">);</code> <code class="c1">// read results...</code> <code class="k">if</code> <code class="o">(</code> <code class="n">urlcon</code><code class="o">.</code><code class="na">getResponseCode</code><code class="o">(</code> <code class="o">)</code> <code class="o">!=</code> <code class="n">HttpURLConnection</code><code class="o">.</code><code class="na">HTTP_OK</code> <code class="o">)</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Posted ok!"</code><code class="o">);</code> <code class="k">else</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="s">"Bad post..."</code><code class="o">);</code> <code class="k">return</code><code class="o">;</code> <code class="o">}</code> <code class="c1">//InputStream in = urlcon.getInputStream( );</code> <code class="c1">// ...</code> <code class="o">}</code> <code class="k">catch</code> <code class="o">(</code><code class="n">MalformedURLException</code> <code class="n">e</code><code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="n">e</code><code class="o">);</code> <code class="c1">// bad postURL</code> <code class="o">}</code> <code class="k">catch</code> <code class="o">(</code><code class="n">IOException</code> <code class="n">e2</code><code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code><code class="n">e2</code><code class="o">);</code> <code class="c1">// I/O error</code> <code class="o">}</code> <code class="o">}</code> <code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code> <code class="n">String</code> <code class="o">[]</code> <code class="n">args</code> <code class="o">)</code> <code class="o">{</code> <code class="n">JFrame</code> <code class="n">frame</code> <code class="o">=</code> <code class="k">new</code> <code class="n">JFrame</code><code class="o">(</code><code class="s">"SimplePost"</code><code class="o">);</code> <code class="n">frame</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="k">new</code> <code class="n">Post</code><code class="o">(</code> <code class="n">args</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">),</code> <code class="s">"Center"</code> <code class="o">);</code> <code class="n">frame</code><code class="o">.</code><code class="na">pack</code><code class="o">(</code> <code class="o">);</code> <code class="n">frame</code><code class="o">.</code><code class="na">setVisible</code><code class="o">(</code><code class="kc">true</code><code class="o">);</code> <code class="o">}</code> <code class="o">}</code></pre><p>When you run this application, you must specify the URL of the server program on the command line. For example:</p><a id="I_14_tt907"/><pre class="programlisting"><code class="o">%</code> <strong class="userinput"><code><code class="n">java</code> <code class="n">Post</code> <code class="nl">http:</code><code class="c1">//</code></code></strong><strong class="userinput"><code><em class="replaceable"><code>www.myserver.example/cgi-bin/login.cgi</code></em></code></strong></pre><p>The beginning of the application creates the form; there’s nothing here that won’t be obvious after you’ve read Chapters <a class="xref" href="ch16.html" title="Chapter 16. Swing">16</a> through <a class="xref" href="ch18.html" title="Chapter 18. More Swing Components">18</a>, which cover the AWT and Swing GUI toolkits. All the magic happens in the protected <code class="literal">postData()</code> method. First, we create a <code class="literal">StringBuffer</code> and load it with name/value pairs, separated by ampersands. (We don’t need the initial question mark when we’re using the <code class="literal">POST</code> method because we’re not appending to a URL string.) Each pair is first encoded using the static <a id="I_indexterm14_id774699" class="indexterm"/><code class="literal">URLEncoder.encode()</code> method. We run the name fields through the encoder as well as the value fields, even though we know that in this case they contain no special characters.</p><p>Next, we set up the connection to the server program. In our previous example, we weren’t required to do anything special to send the data because the request was made by the simple act of opening the URL on the server. Here, we have to carry some of the weight of talking to the remote web server. Fortunately, the <code class="literal">HttpURLConnection</code> object does most of the work for us; we just have to tell it that we want to do a <code class="literal">POST</code> to the URL and the type of data we are sending. We ask for the <code class="literal">URLConnection</code> object that is using the URL’s <code class="literal">openConnection()</code> method. We know that we are using the HTTP protocol so we should be able to cast it to an <code class="literal">HttpURLConnection</code> type, which has the support we need. Because HTTP is one of the guaranteed protocols, we can safely make this assumption.</p><p>We then use <a id="I_indexterm14_id774758" class="indexterm"/><code class="literal">setRequestMethod()</code> to tell the connection we want to do a <code class="literal">POST</code> operation. We also use <a id="I_indexterm14_id774775" class="indexterm"/><code class="literal">setRequestProperty()</code> to set the <code class="literal">Content-Type</code> field of our HTTP request to the appropriate type—in this case, the proper MIME type for encoded form data. (This is necessary to tell the server what kind of data we’re sending.) Finally, we use the <a id="I_indexterm14_id774796" class="indexterm"/><code class="literal">setDoOutput()</code> and <a id="I_indexterm14_id774806" class="indexterm"/><code class="literal">setDoInput()</code> methods to tell the connection that we want to both send and receive stream data. The URL connection infers from this combination that we are going to do a <code class="literal">POST</code> operation and expects a response. Next, we get an output stream from the connection with <code class="literal">getOutputStream()</code> and create a <code class="literal">PrintWriter</code> so that we can easily write our encoded data.</p><p>After we post the data, our application calls <a id="I_indexterm14_id774839" class="indexterm"/><code class="literal">getResponseCode()</code> to see whether the HTTP response code from the server indicates that the <code class="literal">POST</code> was successful. Other response codes (defined as constants in <code class="literal">HttpURLConnection</code>) indicate various failures. At the end of our example, we indicate where we could have read back the text of the response. For this application, we’ll assume that simply knowing that the post was successful is sufficient.</p><p>Although form-encoded data (as indicated by the MIME type we specified for the <a id="I_indexterm14_id774869" class="indexterm"/><code class="literal">Content-Type</code> field) is the most common, other types of communications are possible. We could have used the input and output streams to exchange arbitrary data types with the server program. The <code class="literal">POST</code> operation could send any kind of data; the server application simply has to know how to handle it. One final note: if you are writing an application that needs to decode form data, you can use the <code class="literal">java.net.URLDecoder</code> to undo the operation of the <code class="literal">URLEncoder</code>. If you use the Servlet API, this happens automatically, as you’ll see in <a class="xref" href="ch15.html" title="Chapter 15. Web Applications and Web Services">Chapter 15</a>.<a id="I_indexterm14_id774905" class="indexterm"/><a id="I_indexterm14_id774912" class="indexterm"/></p></div><div class="sect2" title="The HttpURLConnection"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-14-SECT-3.3"/>The HttpURLConnection</h2></div></div></div><p><a id="idx10812" class="indexterm"/> <a id="idx10828" class="indexterm"/>Other information from the request is available from the <code class="literal">HttpURLConnection</code> as well. We could use <a id="I_indexterm14_id774959" class="indexterm"/><code class="literal">getContentType()</code> and <a id="I_indexterm14_id774970" class="indexterm"/><code class="literal">getContentEncoding()</code> to determine the MIME type and encoding of the response. We could also interrogate the HTTP response headers by using <a id="I_indexterm14_id774982" class="indexterm"/><code class="literal">getHeaderField()</code>. (HTTP response headers are metadata name/value pairs carried with the response.) Convenience methods can fetch integer and date-formatted header fields, <a id="I_indexterm14_id775000" class="indexterm"/><code class="literal">getHeaderFieldInt()</code> and <a id="I_indexterm14_id775011" class="indexterm"/><code class="literal">getHeaderFieldDate()</code>, which return an <code class="literal">int</code> and a <code class="literal">long</code> type, respectively. The content length and last modification date are provided through <a id="I_indexterm14_id775034" class="indexterm"/><code class="literal">getContentLength()</code> and <a id="I_indexterm14_id775045" class="indexterm"/><code class="literal">getLastModified()</code>.</p></div><div class="sect2" title="SSL and Secure Web Communications"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-14-SECT-3.4"/>SSL and Secure Web Communications</h2></div></div></div><p><a id="I_indexterm14_id775063" class="indexterm"/> <a id="idx10814" class="indexterm"/> <a id="I_indexterm14_id775080" class="indexterm"/>The previous examples sent a field called <code class="literal">Password</code> to the server. However, standard HTTP doesn’t provide encryption to hide our data. Fortunately, adding security for <code class="literal">GET</code> and <code class="literal">POST</code> operations like this is easy (trivial in fact, for the client-side developer). Where available, you simply have to use a secure form of the HTTP protocol—HTTPS:</p><a id="I_14_tt908"/><pre class="programlisting"><code class="nl">https:</code><code class="c1">//www.myserver.example/cgi-bin/login.cgi</code></pre><p><a id="I_indexterm14_id775123" class="indexterm"/> <a id="I_indexterm14_id775130" class="indexterm"/>HTTPS is a version of the standard HTTP protocol run over Secure Sockets Layer (SSL), which uses public-key encryption techniques to encrypt the browser-to-server communications. Most web browsers and servers currently come with built-in support for HTTPS (or raw SSL sockets). Therefore, if your web server supports HTTPS and has it configured, you can use a browser to send and receive secure data simply by specifying the <a id="I_indexterm14_id775140" class="indexterm"/><code class="literal">https</code> protocol in your URLs. There is much more to learn about SSL and related aspects of security such as authenticating whom you are actually talking to, but as far as basic data encryption goes, this is all you have to do. It is not something your code has to deal with directly. The Java JRE standard edition ships with SSL and HTTPS support, and beginning with Java 5.0, all Java implementations must support HTTPS as well as HTTP for URL connections. We’ll discuss writing secure web applications in more detail in <a class="xref" href="ch15.html" title="Chapter 15. Web Applications and Web Services">Chapter 15</a>.</p></div><div class="sect2" title="URLs, URNs, and URIs"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-14-SECT-3.5"/>URLs, URNs, and URIs</h2></div></div></div><p><a id="idx10816" class="indexterm"/> <a id="idx10818" class="indexterm"/> <a id="idx10819" class="indexterm"/> <a id="idx10820" class="indexterm"/> <a id="idx10826" class="indexterm"/> <a id="idx10827" class="indexterm"/> <a id="idx10829" class="indexterm"/>Earlier, we discussed URLs and distinguished them from the concept of URNs. Whereas a URL points to a specific location on the Net and specifies a protocol or <span class="emphasis"><em>scheme</em></span> for accessing its contents, a URN is simply a globally unique name. A URL is analogous to giving someone your phone number. But a URN is more like giving them your social security number. Your phone number may change, but your social security number is supposed to uniquely identify you forever.</p><p>While it’s possible that some mechanism might be able to look at a given URN and tie it to a location (a URL), it is not necessarily so. URNs are intended only to be permanent, unique, abstract identifiers for an item, whereas a URL is a mechanism you can use to get in touch with a resource right now. You can use a phone number to contact me today, but you can use my social security number to uniquely identify me anytime.</p><p>An example of a URN is <a class="ulink" href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>, which is the identifier for a version of the Extensible Stylesheet Language, standardized by the W3C. Now, it also happens that this is a URL (you can go to that address and find information about the standard), but that is for convenience only. This URN’s primary mission is to uniquely label the version of the programming language in a way that never changes.</p><p>Collectively, URLs and URNs are called Uniform Resource Identifiers or URIs. A URI is simply a URL or URN. So, URLs and URNs are kinds of URIs. The reason for this abstraction is that URLs and URNs, by definition, have some things in common. All URIs are supposed to be human-readable and “transcribable” (it should be possible to write them on the back of a napkin). They always have a hierarchical structure, and they are always unique. Both URLs and URNs also share some common syntax, which is described by RFC 2396.</p><p>The <a id="I_indexterm14_id775299" class="indexterm"/><code class="literal">java.net.URI</code> class formalizes these distinctions. The difference between the URI and URL classes is that the URI class does not try to parse the contents of the identifier and apply any “meaning.” Whereas the URL class immediately attempts to parse the scheme portion of the URL and locate a protocol handler, the URI class doesn’t interpret its content. It serves only to allow us to work with the identifier as structured text, according to the general rules of URI syntax. With the URI class, you can construct the string, resolve relative paths, and perform equality or comparison operations, but no hostname or protocol resolution is done.<a id="I_indexterm14_id775318" class="indexterm"/><a id="I_indexterm14_id775325" class="indexterm"/><a id="I_indexterm14_id775332" class="indexterm"/><a id="I_indexterm14_id775339" class="indexterm"/><a id="I_indexterm14_id775346" class="indexterm"/><a id="I_indexterm14_id775353" class="indexterm"/><a id="I_indexterm14_id775360" class="indexterm"/></p></div></div></body></html>