3
3
< head >
4
4
< meta charset ="utf-8 ">
5
5
< title > Sample routes for akka-http</ title >
6
+ < style >
7
+ body {
8
+ font-family : Arial, sans-serif;
9
+ max-width : 800px ;
10
+ margin : 0 auto;
11
+ padding : 20px ;
12
+ }
13
+
14
+ .section {
15
+ margin : 20px 0 ;
16
+ padding : 15px ;
17
+ border : 1px solid # ddd ;
18
+ border-radius : 5px ;
19
+ }
20
+
21
+ .section h3 {
22
+ margin-top : 0 ;
23
+ color : # 333 ;
24
+ }
25
+
26
+ form {
27
+ margin : 10px 0 ;
28
+ }
29
+
30
+ input , textarea , select {
31
+ margin : 5px ;
32
+ padding : 5px ;
33
+ }
34
+
35
+ button , input [type = "submit" ] {
36
+ background-color : # 4CAF50 ;
37
+ color : white;
38
+ padding : 8px 16px ;
39
+ border : none;
40
+ border-radius : 4px ;
41
+ cursor : pointer;
42
+ }
43
+
44
+ button : hover , input [type = "submit" ]: hover {
45
+ background-color : # 45a049 ;
46
+ }
47
+
48
+ .result {
49
+ margin : 10px 0 ;
50
+ padding : 10px ;
51
+ background-color : # f9f9f9 ;
52
+ border-left : 4px solid # 4CAF50 ;
53
+ display : none;
54
+ }
55
+
56
+ .error {
57
+ border-left-color : # f44336 ;
58
+ background-color : # ffebee ;
59
+ }
60
+ </ style >
6
61
</ head >
7
62
< body >
8
- < a href ="http://127.0.0.1:6002/entries "> entries</ a >
9
- < br >
10
- < a href ="http://127.0.0.1:6002/faultyActor "> faultyActor</ a >
11
- < br >
12
- < form method ="post " action ="http://127.0.0.1:6002/post ">
13
- < label for ="color "> Color:</ label > < br >
14
- < input type ="text " id ="color " name ="color "> < br >
15
- < label for ="age "> Age:</ label > < br >
16
- < input type ="text " id ="age " name ="age "> < br >
17
- < input type ="submit " value ="Submit ">
18
- </ form >
63
+ < h1 > Akka HTTP Sample Routes Demo</ h1 >
64
+
65
+ < div class ="section ">
66
+ < h3 > Browse Directory Entries</ h3 >
67
+ < p > Browse files in the system temp directory:</ p >
68
+ < a href ="http://127.0.0.1:6002/entries " target ="_blank ">
69
+ < button type ="button "> Browse Entries</ button >
70
+ </ a >
71
+ </ div >
72
+
73
+ < div class ="section ">
74
+ < h3 > Form Data Submission</ h3 >
75
+ < p > Submit form data with validation (age must be > 18):</ p >
76
+ < form method ="post " action ="http://127.0.0.1:6002/post ">
77
+ < label for ="color "> Color:</ label > < br >
78
+ < input type ="text " id ="color " name ="color " placeholder ="Enter a color " required > < br > < br >
79
+ < label for ="age "> Age:</ label > < br >
80
+ < input type ="number " id ="age " name ="age " placeholder ="Enter age " required > < br > < br >
81
+ < input type ="submit " value ="Submit Form Data ">
82
+ </ form >
83
+ </ div >
84
+
85
+ < div class ="section ">
86
+ < h3 > Faulty Actor Test</ h3 >
87
+ < p > Test the faulty actor that demonstrates error handling:</ p >
88
+ < p > < em > Note: This actor may behave differently on first vs subsequent requests</ em > </ p >
89
+ < button onclick ="testFaultyActor() "> Test Faulty Actor</ button >
90
+ < button onclick ="testFaultyActorMultiple() "> Test Multiple Times (5x)</ button >
91
+ < button onclick ="clearFaultyResults() "> Clear Results</ button >
92
+ < div id ="faultyResult " class ="result "> </ div >
93
+ < div id ="faultyHistory " style ="margin-top: 10px; "> </ div >
94
+ </ div >
95
+
96
+ < div class ="section ">
97
+ < h3 > Accept Header Test</ h3 >
98
+ < p > Test different Accept headers (always returns JSON):</ p >
99
+ < button onclick ="testAcceptHeader('application/json') "> Test JSON Accept</ button >
100
+ < button onclick ="testAcceptHeader('text/csv') "> Test CSV Accept</ button >
101
+ < button onclick ="testAcceptHeader('text/plain') "> Test Plain Text Accept</ button >
102
+ < button onclick ="testAcceptHeader('text/xml') "> Test XML Accept</ button >
103
+ < div id ="acceptResult " class ="result "> </ div >
104
+ </ div >
105
+
106
+ < div class ="section ">
107
+ < h3 > Raw JSON POST</ h3 >
108
+ < p > Send raw JSON data via POST:</ p >
109
+ < textarea id ="jsonInput " rows ="4 " cols ="50 " placeholder ='{"account":{"name":"TEST"}} '> </ textarea > < br >
110
+ < button onclick ="sendRawJson() "> Send Raw JSON</ button >
111
+ < div id ="jsonResult " class ="result "> </ div >
112
+ </ div >
113
+
114
+ < div class ="section ">
115
+ < h3 > XML Response Test</ h3 >
116
+ < p > Get a sample XML response:</ p >
117
+ < button onclick ="getXmlResponse() "> Get XML Response</ button >
118
+ < div id ="xmlResult " class ="result "> </ div >
119
+ </ div >
120
+
121
+ < div class ="section ">
122
+ < h3 > User Path Matching</ h3 >
123
+ < p > Test different user path patterns:</ p >
124
+ < div style ="background-color: #f0f8ff; padding: 10px; margin: 10px 0; border-left: 4px solid #2196F3; font-family: monospace; ">
125
+ < strong > Path Patterns:</ strong > < br >
126
+ < code > /users</ code > - All users< br >
127
+ < code > /users/{userId}</ code > - Single user (e.g., /users/123)< br >
128
+ < code > /users/{userId}/{action}</ code > - User action (e.g., /users/123/edit)< br >
129
+ < code > /users/{userId}/{action}/...</ code > - Complex nested paths
130
+ </ div >
131
+ < div >
132
+ < a href ="http://127.0.0.1:6002/users " target ="_blank ">
133
+ < button type ="button "> All Users</ button >
134
+ </ a >
135
+ </ div >
136
+ < div >
137
+ < input type ="text " id ="userId " placeholder ="Enter user ID " value ="123 ">
138
+ < button onclick ="testUserPath() "> Test Single User</ button >
139
+ </ div >
140
+ < div >
141
+ < input type ="text " id ="userIdAction " placeholder ="User ID " value ="123 ">
142
+ < input type ="text " id ="userAction " placeholder ="Action " value ="edit ">
143
+ < button onclick ="testUserAction() "> Test User Action</ button >
144
+ </ div >
145
+ < div >
146
+ < input type ="text " id ="complexPath " placeholder ="users/123/edit/profile/settings "
147
+ value ="users/123/edit/profile/settings ">
148
+ < button onclick ="testComplexPath() "> Test Complex Path</ button >
149
+ </ div >
150
+ </ div >
151
+
152
+ < script >
153
+ function showResult ( elementId , content , isError = false ) {
154
+ const resultDiv = document . getElementById ( elementId ) ;
155
+ resultDiv . innerHTML = content ;
156
+ resultDiv . className = isError ? 'result error' : 'result' ;
157
+ resultDiv . style . display = 'block' ;
158
+ }
159
+
160
+ function testAcceptHeader ( acceptType ) {
161
+ fetch ( 'http://127.0.0.1:6002/acceptAll' , {
162
+ method : 'GET' ,
163
+ headers : {
164
+ 'Accept' : acceptType
165
+ }
166
+ } )
167
+ . then ( response => response . json ( ) )
168
+ . then ( data => {
169
+ showResult ( 'acceptResult' , `Accept: ${ acceptType } <br>Response: ${ JSON . stringify ( data ) } ` ) ;
170
+ } )
171
+ . catch ( error => {
172
+ showResult ( 'acceptResult' , `Error: ${ error . message } ` , true ) ;
173
+ } ) ;
174
+ }
175
+
176
+ function sendRawJson ( ) {
177
+ const jsonData = document . getElementById ( 'jsonInput' ) . value || '{"account":{"name":"TEST"}}' ;
178
+
179
+ fetch ( 'http://127.0.0.1:6002/jsonRaw' , {
180
+ method : 'POST' ,
181
+ headers : {
182
+ 'Content-Type' : 'application/json'
183
+ } ,
184
+ body : jsonData
185
+ } )
186
+ . then ( response => {
187
+ if ( response . ok ) {
188
+ showResult ( 'jsonResult' , `JSON sent successfully!<br>Data: ${ jsonData } ` ) ;
189
+ } else {
190
+ showResult ( 'jsonResult' , `Error: ${ response . status } ${ response . statusText } ` , true ) ;
191
+ }
192
+ } )
193
+ . catch ( error => {
194
+ showResult ( 'jsonResult' , `Error: ${ error . message } ` , true ) ;
195
+ } ) ;
196
+ }
197
+
198
+ function getXmlResponse ( ) {
199
+ fetch ( 'http://127.0.0.1:6002/okResponseXml' )
200
+ . then ( response => response . text ( ) )
201
+ . then ( data => {
202
+ // Create a temporary element to safely escape the XML content
203
+ const tempDiv = document . createElement ( 'div' ) ;
204
+ tempDiv . textContent = data ;
205
+ showResult ( 'xmlResult' , `XML Response:<br><pre>${ tempDiv . innerHTML } </pre>` ) ;
206
+ } )
207
+ . catch ( error => {
208
+ showResult ( 'xmlResult' , `Error: ${ error . message } ` , true ) ;
209
+ } ) ;
210
+ }
211
+
212
+ function testUserPath ( ) {
213
+ const userId = document . getElementById ( 'userId' ) . value || '123' ;
214
+ window . open ( `http://127.0.0.1:6002/users/${ userId } ` , '_blank' ) ;
215
+ }
216
+
217
+ function testUserAction ( ) {
218
+ const userId = document . getElementById ( 'userIdAction' ) . value || '123' ;
219
+ const action = document . getElementById ( 'userAction' ) . value || 'edit' ;
220
+ window . open ( `http://127.0.0.1:6002/users/${ userId } /${ action } ` , '_blank' ) ;
221
+ }
222
+
223
+ function testComplexPath ( ) {
224
+ const path = document . getElementById ( 'complexPath' ) . value || 'users/123/edit/profile/settings' ;
225
+ window . open ( `http://127.0.0.1:6002/${ path } ` , '_blank' ) ;
226
+ }
227
+
228
+ // Set default JSON in textarea
229
+ document . getElementById ( 'jsonInput' ) . value = '{"account":{"name":"TEST"}}' ;
230
+
231
+ let faultyTestCount = 0 ;
232
+ let faultyHistory = [ ] ;
233
+
234
+ function testFaultyActor ( ) {
235
+ faultyTestCount ++ ;
236
+ const startTime = new Date ( ) ;
237
+
238
+ showResult ( 'faultyResult' , `Testing faulty actor (Request #${ faultyTestCount } )...` ) ;
239
+
240
+ fetch ( 'http://127.0.0.1:6002/faultyActor' , {
241
+ method : 'GET'
242
+ } )
243
+ . then ( response => {
244
+ const endTime = new Date ( ) ;
245
+ const duration = endTime - startTime ;
246
+
247
+ if ( response . ok ) {
248
+ return response . text ( ) . then ( text => {
249
+ const result = `✅ Request #${ faultyTestCount } - SUCCESS (${ duration } ms)<br>Response: ${ text } ` ;
250
+ showResult ( 'faultyResult' , result ) ;
251
+ addToHistory ( faultyTestCount , 'SUCCESS' , duration , text ) ;
252
+ } ) ;
253
+ } else {
254
+ // Handle error responses (4xx, 5xx status codes)
255
+ return response . text ( ) . then ( text => {
256
+ let errorDisplay = `${ response . status } ${ response . statusText } ` ;
257
+ try {
258
+ const errorResponse = JSON . parse ( text ) ;
259
+ if ( errorResponse . error && errorResponse . message ) {
260
+ errorDisplay = `${ errorResponse . error } : ${ errorResponse . message } ` ;
261
+ } else if ( text ) {
262
+ errorDisplay = text ;
263
+ }
264
+ } catch ( parseError ) {
265
+ if ( text ) {
266
+ errorDisplay = text ;
267
+ }
268
+ }
269
+
270
+ const result = `❌ Request #${ faultyTestCount } - ERROR (${ duration } ms)<br>Status: ${ response . status } <br>Error: ${ errorDisplay } ` ;
271
+ showResult ( 'faultyResult' , result , true ) ;
272
+ addToHistory ( faultyTestCount , 'ERROR' , duration , errorDisplay ) ;
273
+ } ) ;
274
+ }
275
+ } )
276
+ . catch ( error => {
277
+ const endTime = new Date ( ) ;
278
+ const duration = endTime - startTime ;
279
+ const result = `❌ Request #${ faultyTestCount } - FAILED (${ duration } ms)<br>Network Error: ${ error . message } ` ;
280
+ showResult ( 'faultyResult' , result , true ) ;
281
+ addToHistory ( faultyTestCount , 'FAILED' , duration , error . message ) ;
282
+ } ) ;
283
+ }
284
+
285
+ function testFaultyActorMultiple ( ) {
286
+ const delay = 500 ; // 500ms delay between requests
287
+ for ( let i = 0 ; i < 5 ; i ++ ) {
288
+ setTimeout ( ( ) => {
289
+ testFaultyActor ( ) ;
290
+ } , i * delay ) ;
291
+ }
292
+ }
293
+
294
+ function addToHistory ( requestNum , status , duration , response ) {
295
+ const timestamp = new Date ( ) . toLocaleTimeString ( ) ;
296
+ faultyHistory . unshift ( {
297
+ requestNum,
298
+ status,
299
+ duration,
300
+ response,
301
+ timestamp
302
+ } ) ;
303
+
304
+ // Keep only last 10 results
305
+ if ( faultyHistory . length > 10 ) {
306
+ faultyHistory = faultyHistory . slice ( 0 , 10 ) ;
307
+ }
308
+
309
+ updateHistoryDisplay ( ) ;
310
+ }
311
+
312
+ function updateHistoryDisplay ( ) {
313
+ const historyDiv = document . getElementById ( 'faultyHistory' ) ;
314
+ if ( faultyHistory . length === 0 ) {
315
+ historyDiv . innerHTML = '' ;
316
+ return ;
317
+ }
318
+
319
+ let historyHtml = '<h4>Request History:</h4><div style="font-family: monospace; font-size: 12px;">' ;
320
+ faultyHistory . forEach ( entry => {
321
+ const statusColor = entry . status === 'SUCCESS' ? '#4CAF50' : '#f44336' ;
322
+ historyHtml += `
323
+ <div style="margin: 5px 0; padding: 5px; border-left: 3px solid ${ statusColor } ; background-color: #f9f9f9;">
324
+ <strong>#${ entry . requestNum } </strong> [${ entry . timestamp } ]
325
+ <span style="color: ${ statusColor } ;">${ entry . status } </span>
326
+ (${ entry . duration } ms)<br>
327
+ <small>${ entry . response } </small>
328
+ </div>
329
+ ` ;
330
+ } ) ;
331
+ historyHtml += '</div>' ;
332
+ historyDiv . innerHTML = historyHtml ;
333
+ }
334
+
335
+ function clearFaultyResults ( ) {
336
+ faultyTestCount = 0 ;
337
+ faultyHistory = [ ] ;
338
+ document . getElementById ( 'faultyResult' ) . style . display = 'none' ;
339
+ document . getElementById ( 'faultyHistory' ) . innerHTML = '' ;
340
+ }
341
+ </ script >
19
342
</ body >
20
343
</ html >
0 commit comments