Services – TDD mit REST, JSON, Java

Sonntag, 20. April 2014 von  
unter Fachartikel Architektur

Die Motivation

TDD mit Java ist inzwischen ein Grundpfeiler moderner robuster Software-Entwicklung und wird in der Praxis häufig mit JUnit-Tests und weiterführenden Tests mittels EasyMock und Mockito implementiert. Daher hier der Hinweis auf das sehr gute Seminar zum Thema TDD mit Java von Binaris. Für einen schnellen Funktionstest während der Test-getriebenen Entwicklungsphase von WebServices (SOAP, REST) gibt es zusätzlich zum Unit-Testing ebenfalls sehr effektive Werkzeuge mit graphischen Benutzeroberflächen, wie z. B. das SOAP UI.

Auch für RESTful WebServices kann ein RESTService TestClient in Java schnell selbst implementiert werden, der für den Test der vorher in der REST-WebService Schnittstellen-Spezifikation festgelegten Requests und zugehörigen Http-Responses im JSON-Format bestens geeignet ist.

Die Beispiel-Applikation

In diesem Blog-Eintrag soll es also um eine Beispiel-Applikation mit graphischer Benutzerschnittstelle (GUI) gehen ohne Datenbank-Anbindung, die zum schnellen Testen beliebiger REST-Service Aufrufe verwendet werden kann.

Eine simple Java Desktop-Applikation ist mit Bordmitteln schnell erstellt, z. B.  mit der NetBeans IDE: File/New/Project/Java/Java Desktop Application, wobei man den bekannten Hinweis über den ‚deprecated‘ Status einiger Bibliotheken erhält: ‚Note that JSR-296 (Swing Application Framework) is no longer developed…‘., was uns jedoch für die Entwicklung der GUI des TestClients für RESTful WebServices nicht stören soll, da das Swing-Famework für robuste Java-Applikationen leicht handhabbar, weitverbreitet, in der Praxis äußerst bewährt und somit bestens geeignet ist.

Man erhält also ein neues GUI-Grundgerüst, auf dem wir aufbauen können, um die Benutzerschnittstelle des Swing-Dialogs auszugestalten und auszuprogrammieren. NetBeans hat uns praktischerweise gleich zwei für den Test-Client benötigte JAR-Dateien ins lib-Verzeichnis gestellt:

– appframework.jar und
– swing-worker.jar

Aus dem Swing appframework-Package werden die Klasse „SingleFrameApplication“ als Launcher der Test-Applikation und  für die Swing-View die Klasse „FrameView“ verwendet.

Die GUI können wir nun, wie gewohnt, mit Hilfe des NetBeans GUI-Editors hier ausgestalten. Dabei hat NetBeans eine Form-Datei namens SwingRESTClientView.form mit den Properties der GUI-Elemente, die wir auf den Dialog gezogen haben, erstellt.

Nun gibt es natürlich auch die Möglichkeit, das compilierbare Projekt in einer bevorzugten Eclipse-Version einfach in den Eclipse-workspace zu importieren (z.B. wie von mir bevorzugt, in das JBoss Developer Studio). Hierbei wird die SwingRESTClientView.form-Datei ebenfalls unverändert importiert, denn damit können auch nachträglich leicht Änderungen an der Benutzeroberfläche, z.B. mittels GUI-Editor, durchgeführt werden und danach die geänderte SwingRESTClientView.form-Datei einfach erneut in das Eclipse-Projekt importiert werden. Natürlich kann auch direkt ein Swing-GUI Editor innerhalb von Eclipse verwendet werden. Hierüber gibt es bereits einen Blog-Eintrag in diesem Blog hier.

Weitere verwendete Bibliotheken:

a) für die Http-Requests: commons.httpclient.jar von Apache mit diesen Klassen:

org.apache.commons.httpclient.HttpClient;
org.apache.commons.httpclient.HttpMethod;
org.apache.commons.httpclient.methods.DeleteMethod;
org.apache.commons.httpclient.methods.EntityEnclosingMethod;
org.apache.commons.httpclient.methods.GetMethod;
org.apache.commons.httpclient.methods.PostMethod;
org.apache.commons.httpclient.methods.PutMethod;
org.apache.commons.httpclient.methods.StringRequestEntity;

b) für das Logging:

com.sprinsource.org.apache.commons.logging.jar von Apache und Springsource.com

Hier nun die SwingRESTClientView.java, welche von FrameView abgeleitet ist:

/*
 * SwingRESTClientView.java
 */
package de.binaris.swingrestclient;
 
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;
 
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

import org.jdesktop.application.FrameView;
import org.jdesktop.application.SingleFrameApplication;
 
/**
 * The application’s main frame.
 */
public class SwingRESTClientView extends FrameView {
 
    private JButton jButtonClearRequest;
    private JButton jButtonClearResponse;
    private JButton jButtonSendRequest;
    @SuppressWarnings(„rawtypes“)
    private JComboBox jComboBoxMethod;
    private JLabel jLabel1;
    private JLabel jLabel10;
    private JLabel jLabel11;
    private JLabel jLabel12;
    private JLabel jLabel13;
    private JLabel jLabel14;
    private JLabel jLabel15;
    private JLabel jLabel2;
    private JLabel jLabel3;
    private JLabel jLabel4;
    private JLabel jLabel5;
    private JLabel jLabel7;
    private JLabel jLabelDate;
    private JLabel jLabelResultCode;
    private JLabel jLabelURI;
    private JPanel jPanel1;
    private JPanel jPanel2;
    private JPanel jPanel3;
    private JPanel jPanel4;
    private JPanel jPanel5;
    private JPanel jPanel6;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JSplitPane jSplitPane1;
    private JTextArea jTextAreaReqBody;
    private JTextArea jTextAreaResBody;
    private JTextField jTextFieldReqAccept;
    private JTextField jTextFieldReqContentType;
    private JTextField jTextFieldReqURI;
    private JTextField jTextFieldResCacheControl;
    private JTextField jTextFieldResConnection;
    private JTextField jTextFieldResContentEncoding;
    private JTextField jTextFieldResContentLength;
    private JTextField jTextFieldResContentType;
    private JTextField jTextFieldResDate;
    private JTextField jTextFieldResServer;
    private JPanel mainPanel;
    private JMenuBar menuBar;
   
    public SwingRESTClientView(SingleFrameApplication app) {
        super(app);
        initComponents();
 
            initDefaults();
    }
 
      class MethodFactory {
            public MethodFactory() {
                  super();
            }
 
            public HttpMethod getMethod(String methodType, String URI) throws Exception {
                  HttpMethod method = null;
                  if (methodType.equals(„GET“)) {
                        method =  new GetMethod(URI);
                  } else if (methodType.equals(„POST“)) {
                        method = new PostMethod(URI);
                  } else if (methodType.equals(„PUT“)) {
                        method = new PutMethod(URI);
                  } else if (methodType.equals(„DELETE“)) {
                        method = new DeleteMethod(URI);
                  }
                  if (method != null) {
                        // In case of POST or PUT, „Content-Type“ is required
                        if (methodType.equals(„POST“) || methodType.equals(„PUT“)) {
                             ((EntityEnclosingMethod) method).setRequestEntity(new StringRequestEntity(jTextAreaReqBody.getText().trim(), jTextFieldReqContentType.getText().trim(), „UTF-8“));
                        }
                        method.addRequestHeader(„Accept“, jTextFieldReqAccept.getText().trim());
                        return method;
                  }
                  return null;
            }
      }
 
      private void handleSendRequest() {
            String requestURI = jTextFieldReqURI.getText().trim();
            if (!requestURI.isEmpty()) {
                  try {
                        // clear response
                        handleClearResponse();
 
                        // instantiate client
                        HttpClient client = new HttpClient();
 
                        // get method type from factory
                        HttpMethod method = new MethodFactory().getMethod(jComboBoxMethod.getSelectedItem().toString(), requestURI);
 
                        // send http request
                        int statusCode = client.executeMethod(method);
 
                        // update view
                        jLabelURI.setText(requestURI);
                        jLabelResultCode.setText(„“ + statusCode);
                        jTextAreaResBody.setText(new String(method.getResponseBody()));
 
                        // retrieve and display http response data
                        if (method.getResponseHeader(„Cache-Control“) != null) {
                              jTextFieldResCacheControl.setText(method.getResponseHeader(„Cache-Control“).toString());
                        }
 
                        if (method.getResponseHeader(„Connection“) != null) {
                              jTextFieldResConnection.setText(method.getResponseHeader(„Connection“).toString());
                        }
 
                        if (method.getResponseHeader(„Content-Encoding“) != null) {
                              jTextFieldResContentEncoding.setText(method.getResponseHeader(„Content-Encoding“).toString());
                        }
 
                        if (method.getResponseHeader(„Content-Length“) != null) {
                              jTextFieldResContentLength.setText(method.getResponseHeader(„Content-Length“).toString());
                        }
 
                        if (method.getResponseHeader(„Content-Type“) != null) {
                              jTextFieldResContentType.setText(method.getResponseHeader(„Content-Type“).toString());
                        }
 
                        if (method.getResponseHeader(„Date“) != null) {
                              jTextFieldResDate.setText(method.getResponseHeader(„Date“).toString());
                        }
 
                        if (method.getResponseHeader(„Server“) != null) {
                              jTextFieldResServer.setText(method.getResponseHeader(„Server“).toString());
                        }
                  } catch (Exception ex) {
                        ex.printStackTrace();
                        handleClearResponse();
                        // error message
                        jLabelURI.setText(„Error with URI: „ + requestURI);
                        jTextAreaResBody.setText(ex.getMessage());
                  }
            }
      }
 
      private void initDefaults() {
            jTextFieldReqURI.requestFocusInWindow();
      }
 
      private void handleMethodSelection() {
            // for GET or DELETE content type field is not mandatory
            String selectedMethod = jComboBoxMethod.getSelectedItem().toString();
            if (selectedMethod.equals(„POST“) || selectedMethod.equals(„PUT“)) {
                  jTextFieldReqContentType.setEnabled(true);
                  jTextFieldReqContentType.setText(„text/xml“);
            } else {
                  jTextFieldReqContentType.setEnabled(false);
            }
      }
 
      private void handleClearRequest() {
            // clear all request fields
            jTextFieldReqAccept.setText(„“);
            jTextFieldReqContentType.setText(„“);
            jTextFieldReqURI.setText(„“);
            jTextAreaReqBody.setText(„“);
 
            jTextFieldReqURI.requestFocusInWindow();
      }
 
      private void handleClearResponse() {
            // clear all response fields
            jLabelURI.setText(„“);
            jLabelResultCode.setText(„“);
            jTextAreaResBody.setText(„“);
            jTextFieldResCacheControl.setText(„“);
            jTextFieldResConnection.setText(„“);
            jTextFieldResContentEncoding.setText(„“);
            jTextFieldResContentLength.setText(„“);
            jTextFieldResContentType.setText(„“);
            jTextFieldResDate.setText(„“);
            jTextFieldResServer.setText(„“);
      }
 
    @SuppressWarnings({ „unchecked“, „rawtypes“ })
    private void initComponents() {
 
        mainPanel = new JPanel();
        jSplitPane1 = new JSplitPane();
        jPanel1 = new JPanel();
        jPanel3 = new JPanel();
        jLabel1 = new JLabel();
        jTextFieldReqURI = new JTextField();
        jLabel2 = new JLabel();
        jTextFieldReqAccept = new JTextField();
        jLabel3 = new JLabel();
        jComboBoxMethod = new JComboBox();
        jLabel4 = new JLabel();
        jTextFieldReqContentType = new JTextField();
        jPanel4 = new JPanel();
        jScrollPane1 = new JScrollPane();
        jTextAreaReqBody = new JTextArea();
        jButtonClearRequest = new JButton();
        jButtonSendRequest = new JButton();
        jPanel2 = new JPanel();
        jPanel5 = new JPanel();
        jLabel5 = new JLabel();
        jLabelURI = new JLabel();
        jLabel7 = new JLabel();
        jLabelResultCode = new JLabel();
        jScrollPane2 = new JScrollPane();
        jTextAreaResBody = new JTextArea();
        jPanel6 = new JPanel();
        jLabelDate = new JLabel();
        jLabel10 = new JLabel();
        jLabel11 = new JLabel();
        jLabel12 = new JLabel();
        jLabel13 = new JLabel();
        jLabel14 = new JLabel();
        jLabel15 = new JLabel();
        jTextFieldResDate = new JTextField();
        jTextFieldResServer = new JTextField();
        jTextFieldResContentEncoding = new JTextField();
        jTextFieldResContentType = new JTextField();
        jTextFieldResContentLength = new JTextField();
        jTextFieldResCacheControl = new JTextField();
        jTextFieldResConnection = new JTextField();
        jButtonClearResponse = new JButton();
        menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu();
        JMenuItem exitMenuItem = new JMenuItem();
 
        mainPanel.setName(„mainPanel“);
 
        jSplitPane1.setName(„jSplitPane1“);
 
        jPanel1.setName(„jPanel1“);
 
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(de.binaris.swingrestclient.SwingRESTClientApp.class).getContext().getResourceMap(SwingRESTClientView.class);
        jPanel3.setBorder(BorderFactory.createTitledBorder(resourceMap.getString(„jPanel3.border.title“)));
        jPanel3.setName(„jPanel3“);
 
        jLabel1.setText(resourceMap.getString(„jLabel1.text“));
        jLabel1.setName(„jLabel1“);
 
        jTextFieldReqURI.setText(resourceMap.getString(„jTextFieldReqURI.text“));
        jTextFieldReqURI.setName(„jTextFieldReqURI“);
 
        jLabel2.setText(resourceMap.getString(„jLabel2.text“));
        jLabel2.setName(„jLabel2“);
 
        jTextFieldReqAccept.setText(resourceMap.getString(„jTextFieldReqAccept.text“));
        jTextFieldReqAccept.setName(„jTextFieldReqAccept“);
 
        jLabel3.setText(resourceMap.getString(„jLabel3.text“));
        jLabel3.setName(„jLabel3“);
 
        jComboBoxMethod.setModel(new DefaultComboBoxModel(new String[] { „GET“, „POST“, „PUT“, „DELETE“ }));
        jComboBoxMethod.setName(„jComboBoxMethod“);
        jComboBoxMethod.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBoxMethodActionPerformed(evt);
            }
        });
 
        jLabel4.setText(resourceMap.getString(„jLabel4.text“));
        jLabel4.setName(„jLabel4“);
 
        jTextFieldReqContentType.setText(resourceMap.getString(„jTextFieldReqContentType.text“));
        jTextFieldReqContentType.setEnabled(false);
        jTextFieldReqContentType.setName(„jTextFieldReqContentType“);
 
        GroupLayout jPanel3Layout = new GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel2, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel3, GroupLayout.Alignment.TRAILING))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jTextFieldReqAccept, GroupLayout.DEFAULT_SIZE, 160, Short.MAX_VALUE)
                    .addComponent(jTextFieldReqURI, GroupLayout.DEFAULT_SIZE, 160, Short.MAX_VALUE)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jComboBoxMethod, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel4)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextFieldReqContentType)))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jTextFieldReqURI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jTextFieldReqAccept, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3)
                    .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                        .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(jTextFieldReqContentType, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                        .addComponent(jComboBoxMethod, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
 
        jPanel4.setBorder(BorderFactory.createTitledBorder(resourceMap.getString(„jPanel4.border.title“)));
        jPanel4.setName(„jPanel4“);
 
        jScrollPane1.setName(„jScrollPane1“);
 
        jTextAreaReqBody.setColumns(20);
        jTextAreaReqBody.setRows(5);
        jTextAreaReqBody.setName(„jTextAreaReqBody“);
        jScrollPane1.setViewportView(jTextAreaReqBody);
 
        GroupLayout jPanel4Layout = new GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
                .addContainerGap())
        );
 
        jButtonClearRequest.setText(resourceMap.getString(„jButtonClearRequest.text“));
        jButtonClearRequest.setName(„jButtonClearRequest“);
        jButtonClearRequest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonClearRequestActionPerformed(evt);
            }
        });
 
        jButtonSendRequest.setText(resourceMap.getString(„jButtonSendRequest.text“));
        jButtonSendRequest.setName(„jButtonSendRequest“);
        jButtonSendRequest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSendRequestActionPerformed(evt);
            }
        });
 
        GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel4, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jButtonSendRequest)
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonClearRequest)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonClearRequest)
                    .addComponent(jButtonSendRequest))
                .addContainerGap())
        );
 
        jSplitPane1.setLeftComponent(jPanel1);
 
        jPanel2.setName(„jPanel2“);
 
        jPanel5.setBorder(BorderFactory.createTitledBorder(resourceMap.getString(„jPanel5.border.title“)));
        jPanel5.setName(„jPanel5“);
 
        jLabel5.setText(resourceMap.getString(„jLabel5.text“));
        jLabel5.setName(„jLabel5“);
 
        jLabelURI.setFont(resourceMap.getFont(„jLabelURI.font“));
        jLabelURI.setText(resourceMap.getString(„jLabelURI.text“));
        jLabelURI.setName(„jLabelURI“);
 
        jLabel7.setText(resourceMap.getString(„jLabel7.text“));
        jLabel7.setName(„jLabel7“);
 
        jLabelResultCode.setText(resourceMap.getString(„jLabelResultCode.text“));
        jLabelResultCode.setName(„jLabelResultCode“);
 
        jScrollPane2.setName(„jScrollPane2“);
 
        jTextAreaResBody.setColumns(20);
        jTextAreaResBody.setLineWrap(true);
        jTextAreaResBody.setRows(5);
        jTextAreaResBody.setName(„jTextAreaResBody“);
        jScrollPane2.setViewportView(jTextAreaResBody);
 
        GroupLayout jPanel5Layout = new GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel5Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
                    .addGroup(jPanel5Layout.createSequentialGroup()
                        .addGroup(jPanel5Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel5, GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel7, GroupLayout.Alignment.TRAILING))
                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel5Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(jLabelURI, GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)
                            .addComponent(jLabelResultCode, GroupLayout.PREFERRED_SIZE, 125, GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addGroup(jPanel5Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(jLabelURI))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel5Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(jLabelResultCode))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 39, Short.MAX_VALUE)
                .addContainerGap())
        );
 
        jPanel6.setBorder(BorderFactory.createTitledBorder(resourceMap.getString(„jPanel6.border.title“)));
        jPanel6.setName(„jPanel6“);
 
        jLabelDate.setText(resourceMap.getString(„jLabelDate.text“));
        jLabelDate.setName(„jLabelDate“);
 
        jLabel10.setText(resourceMap.getString(„jLabel10.text“));
        jLabel10.setName(„jLabel10“);
 
        jLabel11.setText(resourceMap.getString(„jLabel11.text“));
        jLabel11.setName(„jLabel11“);
 
        jLabel12.setText(resourceMap.getString(„jLabel12.text“));
        jLabel12.setName(„jLabel12“);
 
        jLabel13.setText(resourceMap.getString(„jLabel13.text“));
        jLabel13.setName(„jLabel13“);
 
        jLabel14.setText(resourceMap.getString(„jLabel14.text“));
        jLabel14.setName(„jLabel14“);
 
        jLabel15.setText(resourceMap.getString(„jLabel15.text“));
        jLabel15.setName(„jLabel15“);
 
        jTextFieldResDate.setText(resourceMap.getString(„jTextFieldResDate.text“));
        jTextFieldResDate.setName(„jTextFieldResDate“);
 
        jTextFieldResServer.setText(resourceMap.getString(„jTextFieldResServer.text“));
        jTextFieldResServer.setName(„jTextFieldResServer“);
 
        jTextFieldResContentEncoding.setText(resourceMap.getString(„jTextFieldResContentEncoding.text“));
        jTextFieldResContentEncoding.setName(„jTextFieldResContentEncoding“);
 
        jTextFieldResContentType.setText(resourceMap.getString(„jTextFieldResContentType.text“));
        jTextFieldResContentType.setName(„jTextFieldResContentType“);
 
        jTextFieldResContentLength.setText(resourceMap.getString(„jTextFieldResContentLength.text“));
        jTextFieldResContentLength.setName(„jTextFieldResContentLength“);
 
        jTextFieldResCacheControl.setText(resourceMap.getString(„jTextFieldResCacheControl.text“));
        jTextFieldResCacheControl.setName(„jTextFieldResCacheControl“);
 
        jTextFieldResConnection.setText(resourceMap.getString(„jTextFieldResConnection.text“));
        jTextFieldResConnection.setName(„jTextFieldResConnection“);
 
        GroupLayout jPanel6Layout = new GroupLayout(jPanel6);
        jPanel6.setLayout(jPanel6Layout);
        jPanel6Layout.setHorizontalGroup(
            jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jLabelDate, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel10, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel11, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel12, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel13, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel14, GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel15, GroupLayout.Alignment.TRAILING))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jTextFieldResServer, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                    .addComponent(jTextFieldResDate, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                    .addComponent(jTextFieldResContentEncoding, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                    .addComponent(jTextFieldResContentType, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                    .addComponent(jTextFieldResContentLength, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                    .addComponent(jTextFieldResCacheControl, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
                    .addComponent(jTextFieldResConnection, GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel6Layout.setVerticalGroup(
            jPanel6Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(jPanel6Layout.createSequentialGroup()
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabelDate)
                    .addComponent(jTextFieldResDate, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel10)
                    .addComponent(jTextFieldResServer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel11)
                    .addComponent(jTextFieldResContentEncoding, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel12)
                    .addComponent(jTextFieldResContentType, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel13)
                    .addComponent(jTextFieldResContentLength, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel14)
                    .addComponent(jTextFieldResCacheControl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel15)
                    .addComponent(jTextFieldResConnection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addContainerGap(16, Short.MAX_VALUE))
        );
 
        jButtonClearResponse.setText(resourceMap.getString(„jButtonClearResponse.text“));
        jButtonClearResponse.setName(„jButtonClearResponse“);
        jButtonClearResponse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonClearResponseActionPerformed(evt);
            }
        });
 
        GroupLayout jPanel2Layout = new GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel6, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel5, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jButtonClearResponse))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel5, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonClearResponse)
                .addContainerGap())
        );
 
        jSplitPane1.setRightComponent(jPanel2);
 
        GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, GroupLayout.DEFAULT_SIZE, 655, Short.MAX_VALUE)
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
        );
 
        menuBar.setName(„menuBar“);
 
        fileMenu.setText(resourceMap.getString(„fileMenu.text“));
        fileMenu.setName(„fileMenu“);
 
        ActionMap actionMap = org.jdesktop.application.Application.getInstance(de.binaris.swingrestclient.SwingRESTClientApp.class).getContext().getActionMap(SwingRESTClientView.class, this);
        exitMenuItem.setAction(actionMap.get(„quit“));
        exitMenuItem.setName(„exitMenuItem“);
        fileMenu.add(exitMenuItem);
 
        menuBar.add(fileMenu);
 
        setComponent(mainPanel);
        setMenuBar(menuBar);
    }
 
private void jComboBoxMethodActionPerformed(java.awt.event.ActionEvent evt) {
    handleMethodSelection();
}
 
private void jButtonClearRequestActionPerformed(java.awt.event.ActionEvent evt) {
    handleClearRequest();
}
 
private void jButtonClearResponseActionPerformed(java.awt.event.ActionEvent evt) {
    handleClearResponse();
}
 
private void jButtonSendRequestActionPerformed(java.awt.event.ActionEvent evt) {
    handleSendRequest();
}
}

Und hier auch noch die SwingRESTClientApp:

/*
 * SwingRESTClientApp.java
 */
package de.binaris.swingrestclient;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;
/**
 * The main class of the application.
 */
public class SwingRESTClientApp extends SingleFrameApplication {
    /**
     * At startup create and show the main frame of the application.
     */
    @Override
    protected void startup() {
        show(new SwingRESTClientView(this));
    }
    /**
     * This method initializes the specified window by injecting resources.
     * Windows shown in the application however are initialized by the GUI
     * builder, therefore additional configuration is not required.
     */
    @Override
    protected void configureWindow(java.awt.Window root) {
    }
    /**
     * static getter for the application instance, convenience method
     *
     * @return the instance of SwingRESTClientApp
     */
    public static SwingRESTClientApp getApplication() {
        return Application.getInstance(SwingRESTClientApp.class);
    }
    /**
     * main method to launch the app.
     */
    public static void main(String[] args) {
        launch(SwingRESTClientApp.class, args);
    }
}

Diese Datei erinnert schon etwas an die GUI-Application Klasse z. B. der folgenden BlackBerry Sample Datei namens NumberGuess.java, wobei der NumberGuessScreen unserer von der Swing FrameView abgeleiteten Klasse entspricht. Wieder ein weiterer Hinweis dafür, dass Entwicklungs-Erfahrung mit dem Swing-Framwork für jeden Java-Entwickler eine gute Basis für den Einstieg in die Entwicklung mobiler Java-Applikationen für BlackBerry-Geräte ist:

package numberguess;
import net.rim.device.api.ui.UiApplication;
/**
 * This class extends the UiApplication class, providing a
 * graphical user interface.
 */
public class NumberGuess extends UiApplication
{
    /**
     * Entry point for application
     * @param args Command line arguments (not used)
     */
    public static void main(String[] args)
    {
        // create a new instance of the application and make the currently
        // running thread the application’s event dispatch thread.
        NumberGuess theApp = new NumberGuess();      
        theApp.enterEventDispatcher();
    }
    /**
     * creates a new NumberGuess object
     */
    public NumberGuess() {       
        // push a screen onto the UI stack for rendering.
        pushScreen(new NumberGuessScreen());
    }   
}

Hier nun der Swing REST-Client als Projekt zum Download.

Die Beispiel-Eingaben in den SwingRESTClient Dialog für die Registrierung eines neuen Users per REST-JSON Request könnten gemäß unser REST-WebService Schnittstellen-Spezifikation z. B. folgendermaßen lauten:

Url: http://myserver.com:8082/JsonServer/rest/RegisterUser
HTTP method: POST
ContentType: application/json
ContentToSend:
{„register“:{„user“:“chuck_norris“,“password“:“bananaboat“,“customerno“:“532792757cc0d517″}}


JSON-Responses:
{„result“:“true“,“registered“:“1″},
wenn der User der customerno problemlos registriert wurde,
oder bereits registriert war


{„result“:“false“,“registered“:“0″},
wenn der User der customerno noch nicht registriert ist
und zur Zeit keine User registriert werden können

An dieser Stelle darf nochmals auf das sehr gute Seminar zum Thema „TDD mit Java“ von Binaris

hier hingewiesen werden.

Allen interessierten Leserinnen und Lesern noch eine schöne Osterzeit.

Kommentare

Einen Kommentar hinzufügen...

Sie müssen registriert und angemeldet sein um einen Kommentar zu schreiben.