Ajout du HttpClient

This commit is contained in:
Alexis Delhaie
2019-10-17 21:54:50 +02:00
parent b65f631cb7
commit 3d09d37411
50 changed files with 405 additions and 180 deletions

View File

@@ -0,0 +1,20 @@
package ovh.alexisdelhaie.curling.dataSet;
public class HeaderModel {
private String key;
private String value;
public HeaderModel(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,128 @@
package ovh.alexisdelhaie.curling.web;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class Client {
private String body;
private Map<String, String> headers;
private Method method;
private String url;
private RequestError error;
private String log;
public String getBody() {
return body;
}
public Map<String, String> getHeaders() {
return headers;
}
public Method getMethod() {
return method;
}
public String getUrl() {
return url;
}
public RequestError getError() {
return error;
}
public void setBody(String body) {
this.body = body;
}
public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}
public void setMethod(Method method) {
this.method = method;
}
public void setUrl(String url) {
this.url = url;
}
public Client(String body, Map<String, String> headers, Method method, String url) {
this.body = body;
this.headers = headers;
this.method = method;
this.url = url;
this.log = "";
}
public CompletableFuture<String> run() {
HttpClient httpClient = HttpClient.newBuilder().build();
try {
HttpRequest request = requestBuilder();
if (request != null) {
return CompletableFuture.supplyAsync(() -> {
String result = String.format("%s\n\n", log);
try {
HttpResponse r = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
result += String.format("> Status : %d\n", r.statusCode());
for(Map.Entry<String, List<String>> header : r.headers().map().entrySet()) {
result += String.format("> %s: ", header.getKey());
for(String s : header.getValue()) {
result += s;
}
result += "\n";
}
result += String.format("\n%s", (String)r.body());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
});
} else {
error = new RequestError("Requete invalide", "La requete est vide");
}
} catch (URISyntaxException e) {
error = new RequestError("URL invalide", "Le format de l'URL est invalide", e);
}
return null;
}
private HttpRequest requestBuilder() throws URISyntaxException {
log += "< ";
HttpRequest.Builder b;
b = HttpRequest.newBuilder(new URI(url));
switch (method) {
case GET: b.GET(); log += "GET"; break;
case POST: b.POST(HttpRequest.BodyPublishers.ofString(body)); log += "POST"; break;
case PUT: b.PUT(HttpRequest.BodyPublishers.ofString(body)); log += "PUT"; break;
case DELETE: b.DELETE(); log += "DELETE"; break;
}
log += String.format(" %s\n", url);
for (Map.Entry<String, String> header : headers.entrySet()) {
b.setHeader(header.getKey(), header.getValue());
log += String.format("< %s: %s", header.getKey(), header.getValue());
}
if(method == Method.POST || method == Method.PUT) {
log += String.format("%s", body);
}
return b.build();
}
}

View File

@@ -0,0 +1,8 @@
package ovh.alexisdelhaie.curling.web;
public enum Method {
GET,
POST,
PUT,
DELETE
}

View File

@@ -0,0 +1,34 @@
package ovh.alexisdelhaie.curling.web;
public class RequestError {
private String title;
private String message;
private Exception e;
public RequestError(String title, String message, Exception exception) {
this.title = title;
this.message = message;
this.e = exception;
}
public RequestError(String title, String message) {
this(title, message, null);
}
public String getTitle() {
return title;
}
public String getMessage() {
return message;
}
public Exception getException() {
return e;
}
public boolean hasException() {
return (e != null);
}
}

View File

@@ -1,5 +1,7 @@
package ovh.alexisdelhaie.curling.windows;
import ovh.alexisdelhaie.curling.dataSet.HeaderModel;
import javax.swing.*;
import java.awt.event.*;
@@ -13,10 +15,9 @@ public class AddHeader extends JDialog {
private JTextField keyField;
private JTextField valueField;
private String value;
private HeaderModel result;
public AddHeader() {
this.value = "";
setContentPane(contentPane);
setModal(true);
setTitle(WINDOW_TITLE);
@@ -51,11 +52,8 @@ public class AddHeader extends JDialog {
}
private void onOK() {
if(!keyField.getText().isBlank()) {
value = keyField.getText();
if(!valueField.getText().isBlank()) {
value += String.format(": %s", valueField.getText());
}
if(!keyField.getText().isBlank() && !valueField.getText().isBlank()) {
result = new HeaderModel(keyField.getText(), valueField.getText());
}
dispose();
}
@@ -64,9 +62,9 @@ public class AddHeader extends JDialog {
dispose();
}
public String getValue() {
public HeaderModel getValue() {
pack();
setVisible(true);
return value;
return result;
}
}

View File

@@ -1,5 +1,7 @@
package ovh.alexisdelhaie.curling.windows;
import ovh.alexisdelhaie.curling.dataSet.HeaderModel;
import javax.swing.*;
import java.awt.event.*;
import java.io.UnsupportedEncodingException;
@@ -7,7 +9,7 @@ import java.util.Base64;
public class BasicAuthenticationDialog extends JDialog {
public static String HTTP_AUTH_BASIC_PATTERN = "Authorization: Basic %s";
public static String HTTP_AUTH_HEADER_KEY = "Authorization";
public static String WINDOW_TITLE = "Authentification HTTP";
private JPanel contentPane;
@@ -16,7 +18,7 @@ public class BasicAuthenticationDialog extends JDialog {
private JTextField textField1;
private JPasswordField passwordField1;
private String value = "";
private HeaderModel result;
public BasicAuthenticationDialog() {
setContentPane(contentPane);
@@ -60,7 +62,7 @@ public class BasicAuthenticationDialog extends JDialog {
.encode(String.format("%s:%s", user, password).getBytes());
try {
String authEncoded = new String(authEncodedBytes, "UTF-8");
value = String.format(HTTP_AUTH_BASIC_PATTERN, authEncoded);
result = new HeaderModel(HTTP_AUTH_HEADER_KEY,String.format("Basic %s", authEncoded));
dispose();
} catch (UnsupportedEncodingException ex) {
JOptionPane.showMessageDialog(this, "Le format UTF-8 n'est pas supporté");
@@ -82,9 +84,9 @@ public class BasicAuthenticationDialog extends JDialog {
dispose();
}
public String showDialog() {
public HeaderModel showDialog() {
pack();
setVisible(true);
return value;
return result;
}
}

View File

@@ -8,6 +8,8 @@ import java.util.Base64;
public class FormEncodedDialog extends JDialog {
public static String WINDOW_TITLE = "Formulaire de données";
public static String[] UNENCODED_CHAR = {"!", "*", "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "#", "[", "]"};
public static String[] ENCODED_CHAR = {"%21", "%2A", "%27", "%28", "%29", "%3B", "%3A", "%40", "%26", "%3D", "%2B", "%24", "%2C", "%2F", "%3F", "%23", "%5B", "%5D"};
private JPanel contentPane;
private JButton buttonOK;
@@ -20,8 +22,6 @@ public class FormEncodedDialog extends JDialog {
private String resultValue = "";
private DefaultListModel<String> model;
public static String[] UNENCODED_CHAR = {"!", "*", "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "#", "[", "]"};
public static String[] ENCODED_CHAR = {"%21", "%2A", "%27", "%28", "%29", "%3B", "%3A", "%40", "%26", "%3D", "%2B", "%24", "%2C", "%2F", "%3F", "%23", "%5B", "%5D"};
public FormEncodedDialog() {
setContentPane(contentPane);

View File

@@ -8,18 +8,7 @@
<properties/>
<border type="none" title="cURLing"/>
<children>
<component id="15009" class="javax.swing.JTextArea" binding="textArea1" default-binding="true">
<constraints>
<grid row="0" column="3" row-span="5" col-span="2" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="50"/>
</grid>
</constraints>
<properties>
<editable value="false"/>
<focusable value="false"/>
</properties>
</component>
<component id="b4b69" class="javax.swing.JComboBox" binding="comboBox1" default-binding="true">
<component id="b4b69" class="javax.swing.JComboBox" binding="httpTypeBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -30,7 +19,7 @@
</model>
</properties>
</component>
<component id="dc7ca" class="javax.swing.JComboBox" binding="comboBox2" default-binding="true">
<component id="dc7ca" class="javax.swing.JComboBox" binding="methodBox">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
@@ -43,7 +32,7 @@
</model>
</properties>
</component>
<component id="3d00f" class="javax.swing.JTextField" binding="textField1" default-binding="true">
<component id="3d00f" class="javax.swing.JTextField" binding="urlField">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
@@ -131,11 +120,27 @@
<grid row="5" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<enabled value="true"/>
<label value="Start"/>
<text value="Start"/>
</properties>
</component>
<scrollpane id="1b18">
<constraints>
<grid row="0" column="3" row-span="5" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="42347" class="javax.swing.JTextArea" binding="httpResponseArea">
<constraints/>
<properties>
<editable value="false"/>
<font name="Courier 10 Pitch" size="12"/>
</properties>
</component>
</children>
</scrollpane>
</children>
</grid>
</form>

View File

@@ -1,17 +1,31 @@
package ovh.alexisdelhaie.curling.windows;
import ovh.alexisdelhaie.curling.dataSet.HeaderModel;
import ovh.alexisdelhaie.curling.web.Client;
import ovh.alexisdelhaie.curling.web.Method;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.net.http.HttpClient;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class MainWindow extends JDialog {
private DefaultListModel<String> model;
public static int WINDOW_HEIGHT = 700;
public static int WINDOW_WIDTH = 1100;
public static String WINDOW_TITLE = "cURLing";
public static String CONTENT_TYPE = "content-type";
public static String WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
private JPanel contentPane;
private JTextField textField1;
private JTextArea textArea1;
private JComboBox comboBox1;
private JComboBox comboBox2;
private JTextField urlField;
private JTextArea httpResponseArea;
private JComboBox httpTypeBox;
private JComboBox methodBox;
private JButton xFormEncodedButton;
private JTextArea bodyArea;
private JProgressBar progressBar1;
@@ -20,13 +34,14 @@ public class MainWindow extends JDialog {
private JButton addAuthButton;
private JButton runButton;
public static int WINDOW_HEIGHT = 700;
public static int WINDOW_WIDTH = 1100;
public static String WINDOW_TITLE = "cURLing";
private DefaultListModel<String> model;
private Map<String, String> headers;
private Map<String, String> params;
public MainWindow() {
super((Dialog) null);
setTitle(WINDOW_TITLE);
headers = new HashMap<>();
model = new DefaultListModel<>();
list1.setModel(model);
setContentPane(contentPane);
@@ -36,19 +51,21 @@ public class MainWindow extends JDialog {
newHeaderButton.addActionListener((event) -> {
AddHeader ah = new AddHeader();
String header = ah.getValue();
model.addElement(header);
list1.updateUI();
HeaderModel h = ah.getValue();
if(h != null) {
headers.put(h.getKey(), h.getValue());
updateHeaderList();
}
});
addAuthButton.addActionListener((event) -> {
if(addAuthButton.isEnabled()) {
BasicAuthenticationDialog bad = new BasicAuthenticationDialog();
String auth = bad.showDialog();
if(!auth.isBlank()) {
HeaderModel h = bad.showDialog();
if(h != null) {
headers.put(h.getKey(), h.getValue());
updateHeaderList();
addAuthButton.setEnabled(false);
model.addElement(auth);
list1.updateUI();
}
}
});
@@ -57,7 +74,74 @@ public class MainWindow extends JDialog {
FormEncodedDialog fe = new FormEncodedDialog();
String datas = fe.showDialog();
bodyArea.setText(datas);
headers.put(CONTENT_TYPE, WWW_FORM_URLENCODED);
updateHeaderList();
});
runButton.addActionListener(this::start);
}
private void updateHeaderList() {
model.clear();
for(Map.Entry<String, String> entry : headers.entrySet()) {
String header = String.format("%s: %s", entry.getKey(), entry.getValue());
model.addElement(header);
}
list1.updateUI();
}
private void start(ActionEvent ev) {
startLoading(true);
Client c = new Client(bodyArea.getText(), headers, getMethod(), urlBuilder());
CompletableFuture<String> f = c.run();
new Thread(new Runnable() {
@Override
public void run() {
try {
httpResponseArea.setText(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
startLoading(false);
}
}
}).start();
}
private String urlBuilder() {
return String.format("%s://%s", ((String) httpTypeBox.getSelectedItem()).toLowerCase(), urlField.getText());
}
private Method getMethod() {
if (methodBox.getSelectedItem().equals("GET")) {
return Method.GET;
} else if (methodBox.getSelectedItem().equals("POST")) {
return Method.POST;
} else if (methodBox.getSelectedItem().equals("PUT")) {
return Method.PUT;
} else if (methodBox.getSelectedItem().equals("DELETE")) {
return Method.DELETE;
}
return Method.GET;
}
private void setDisabledComponents(boolean b) {
urlField.setEnabled(!b);
httpTypeBox.setEnabled(!b);
methodBox.setEnabled(!b);
xFormEncodedButton.setEnabled(!b);
bodyArea.setEnabled(!b);
list1.setEnabled(!b);
newHeaderButton.setEnabled(!b);
addAuthButton.setEnabled(!b);
runButton.setEnabled(!b);
}
private void startLoading(boolean b) {
setDisabledComponents(b);
progressBar1.setIndeterminate(b);
}
public void showFrame() {