33< head >
44 < meta charset ="utf-8 ">
55 < 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 >
661</ head >
762< 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 >
19342</ body >
20343</ html >
0 commit comments