Repository: slackapi/java-slack-sdk
Issue: url_verification request fails with bolt-micronaut

Trying to setup the Event API on the Slack App website and setting up the Event callback URL, seems Bolt is not able to parse the `UrlVerificationRequest` properly.

I'm running Java 9 (through Kotlin), with Bolt 1.0.4 on Windows 10

```
[pool-1-thread-2] WARN com.slack.api.bolt.util.SlackRequestParser - No request pattern detected for token=[some_token]&challenge=2dasp7C5rbnT22y2v3IAT95S6WnNUtdpnFckQEQyGl7HjnTa0Y0K&type=url_verification
[pool-1-thread-2] DEBUG io.micronaut.http.server.netty.RoutingInBoundHandler - Encoding emitted response object [Invalid Request] using codec: io.micronaut.runtime.http.codec.TextPlainCodec@28561ca6
```

Changed files:
bolt-micronaut/src/test/java/example/app/AppFactory.java
bolt-micronaut/src/test/java/test_locally/app/CommandsTest.java
bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppMicronautAdapter.java
bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppController.java
bolt-micronaut/src/test/java/test_locally/ControllerTest.java
bolt-micronaut/src/test/java/test_locally/AdapterTest.java

diff --git a/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppController.java b/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppController.java
index 7a2ab34a..287f098b 100644
--- a/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppController.java
+++ b/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppController.java
@@ -9,8 +9,6 @@ import io.micronaut.http.annotation.Body;
 import io.micronaut.http.annotation.Controller;
 import io.micronaut.http.annotation.Post;
 
-import java.util.LinkedHashMap;
-
 /**
  * The default Web controller that works in Micronaut apps.
  * This component requires singleton {@link App} instance managed by the Micronaut DI container.
@@ -30,7 +28,7 @@ public class SlackAppController {
     }
 
     @Post(value = "/events", consumes = {MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON})
-    public HttpResponse<String> dispatch(HttpRequest<String> request, @Body LinkedHashMap<String, String> body) throws Exception {
+    public HttpResponse<String> dispatch(HttpRequest<String> request, @Body String body) throws Exception {
         Request<?> slackRequest = adapter.toSlackRequest(request, body);
         return adapter.toMicronautResponse(slackApp.run(slackRequest));
     }
diff --git a/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppMicronautAdapter.java b/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppMicronautAdapter.java
index 3755bf72..fc5d58b8 100644
--- a/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppMicronautAdapter.java
+++ b/bolt-micronaut/src/main/java/com/slack/api/bolt/micronaut/SlackAppMicronautAdapter.java
@@ -13,14 +13,10 @@ import io.micronaut.http.server.netty.NettyHttpResponseFactory;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.inject.Singleton;
-import java.io.UnsupportedEncodingException;
 import java.net.InetSocketAddress;
-import java.net.URLEncoder;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * The default adaptor that translates Micronaut specific interfaces into Bolt's ones.
@@ -36,16 +32,7 @@ public class SlackAppMicronautAdapter {
         this.requestParser = new SlackRequestParser(appConfig);
     }
 
-    public Request<?> toSlackRequest(HttpRequest<?> req, LinkedHashMap<String, String> body) {
-        String requestBody = body.entrySet().stream().map(e -> {
-            try {
-                String k = URLEncoder.encode(e.getKey(), "UTF-8");
-                String v = URLEncoder.encode(e.getValue(), "UTF-8");
-                return k + "=" + v;
-            } catch (UnsupportedEncodingException ex) {
-                return e.getKey() + "=" + e.getValue();
-            }
-        }).collect(Collectors.joining("&"));
+    public Request<?> toSlackRequest(HttpRequest<?> req, String requestBody) {
         RequestHeaders headers = new RequestHeaders(
                 req.getHeaders() != null ? req.getHeaders().asMap() : Collections.emptyMap());
 
diff --git a/bolt-micronaut/src/test/java/example/app/AppFactory.java b/bolt-micronaut/src/test/java/example/app/AppFactory.java
index ded24300..c37fe358 100644
--- a/bolt-micronaut/src/test/java/example/app/AppFactory.java
+++ b/bolt-micronaut/src/test/java/example/app/AppFactory.java
@@ -1,10 +1,10 @@
 package example.app;
 
-import com.slack.api.bolt.App;
-import com.slack.api.bolt.AppConfig;
 import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
+import com.slack.api.bolt.App;
+import com.slack.api.bolt.AppConfig;
 import io.micronaut.context.annotation.Factory;
 
 import javax.inject.Singleton;
diff --git a/bolt-micronaut/src/test/java/test_locally/AdapterTest.java b/bolt-micronaut/src/test/java/test_locally/AdapterTest.java
index b790eff2..2df7fbe1 100644
--- a/bolt-micronaut/src/test/java/test_locally/AdapterTest.java
+++ b/bolt-micronaut/src/test/java/test_locally/AdapterTest.java
@@ -7,15 +7,16 @@ import com.slack.api.bolt.response.Response;
 import io.micronaut.core.convert.DefaultConversionService;
 import io.micronaut.http.HttpRequest;
 import io.micronaut.http.HttpResponse;
-import io.micronaut.http.MediaType;
 import io.micronaut.http.simple.SimpleHttpHeaders;
 import io.micronaut.http.simple.SimpleHttpParameters;
 import org.junit.Test;
 
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -39,11 +40,7 @@ public class AdapterTest {
         SimpleHttpParameters parameters = new SimpleHttpParameters(params, new DefaultConversionService());
         when(req.getParameters()).thenReturn(parameters);
 
-        LinkedHashMap<String, String> body = new LinkedHashMap<>();
-        body.put("token", "random");
-        body.put("ssl_check", "1");
-
-        Request<?> slackRequest = adapter.toSlackRequest(req, body);
+        Request<?> slackRequest = adapter.toSlackRequest(req, "token=random&ssl_check=1");
 
         assertNotNull(slackRequest);
         assertEquals("token=random&ssl_check=1", slackRequest.getRequestBodyAsString());
@@ -61,11 +58,7 @@ public class AdapterTest {
         InetSocketAddress isa = new InetSocketAddress("localhost", 443);
         when(req.getRemoteAddress()).thenReturn(isa);
 
-        LinkedHashMap<String, String> body = new LinkedHashMap<>();
-        body.put("token", "random");
-        body.put("ssl_check", "1");
-
-        Request<?> slackRequest = adapter.toSlackRequest(req, body);
+        Request<?> slackRequest = adapter.toSlackRequest(req, "token=random&ssl_check=1");
 
         assertNotNull(slackRequest);
         assertEquals("127.0.0.1", slackRequest.getClientIpAddress());
diff --git a/bolt-micronaut/src/test/java/test_locally/ControllerTest.java b/bolt-micronaut/src/test/java/test_locally/ControllerTest.java
index e76a74c6..06a730ab 100644
--- a/bolt-micronaut/src/test/java/test_locally/ControllerTest.java
+++ b/bolt-micronaut/src/test/java/test_locally/ControllerTest.java
@@ -12,7 +12,6 @@ import io.micronaut.http.simple.SimpleHttpParameters;
 import org.junit.Test;
 
 import java.util.HashMap;
-import java.util.LinkedHashMap;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -33,11 +32,7 @@ public class ControllerTest {
         SimpleHttpParameters parameters = new SimpleHttpParameters(new HashMap<>(), new DefaultConversionService());
         when(req.getParameters()).thenReturn(parameters);
 
-        LinkedHashMap<String, String> body = new LinkedHashMap<>();
-        body.put("token", "random");
-        body.put("ssl_check", "1");
-
-        HttpResponse<String> response = controller.dispatch(req, body);
+        HttpResponse<String> response = controller.dispatch(req, "token=random&ssl_check=1");
         assertEquals(200, response.getStatus().getCode());
     }
 
diff --git a/bolt-micronaut/src/test/java/test_locally/app/CommandsTest.java b/bolt-micronaut/src/test/java/test_locally/app/CommandsTest.java
index b028812a..3ac8dc1e 100644
--- a/bolt-micronaut/src/test/java/test_locally/app/CommandsTest.java
+++ b/bolt-micronaut/src/test/java/test_locally/app/CommandsTest.java
@@ -1,12 +1,12 @@
 package test_locally.app;
 
-import com.slack.api.Slack;
 import com.slack.api.RequestConfigurator;
+import com.slack.api.Slack;
+import com.slack.api.app_backend.SlackSignature;
+import com.slack.api.bolt.AppConfig;
 import com.slack.api.methods.MethodsClient;
 import com.slack.api.methods.SlackApiException;
 import com.slack.api.methods.response.auth.AuthTestResponse;
-import com.slack.api.app_backend.SlackSignature;
-import com.slack.api.bolt.AppConfig;
 import io.micronaut.context.annotation.Primary;
 import io.micronaut.http.HttpRequest;
 import io.micronaut.http.HttpResponse;