RESTfull Services in Spring 3 MVC

SpringSourceΤα τελευταία χρόνια, το έχει γίνει η ντε φάκτο εναλλακτική λύση αντί για τις SOAP / WSDL /WS αρχιτεκτονικές. Δε μπορούσε λοιπόν να μείνει απ’εξω από τη τελευταία έκδοση του Spring τη 3.0.

Έτσι λοιπόν κατασκεύασαν μια υλοποίηση για ‘RESTful’ Web services και application και τις ενσωμάτωσαν στο @Controller model του Spring MVC.

RESTful χαρακτηριστικά στο Spring MVC 3.0

URI Templates

Ένα από τα πολύ σημαντικά χαρακτηριστικά είναι τα uri templates.

Μέχρι τώρα ήταν σχετικά δύσκολο να έχεις friendly urls. Έπρεπε να χρησιμοποιήσεις url rewriting αρκετές «πατέντες» ή κάποιο ποιο εξειδικευμένο κομμάτι του framework που να σου δίνει flows και να μανατζάρει όλο αυτό το κομμάτι.

Ένα uri mapping μπορεί να είναι της μορφής

 

/this/is/a/path/to/{somewhere}

Οπότε ο controller θα απαντήσει και κάθε μια από τις περιπτώσεις

/this/is/a/path/to/hell

/this/is/a/path/to/heaven

/this/is/a/path/to/salvation

κλπ

Ακόμα το uri mapping μπορεί να είναι της μορφής

/this/is/a/path/from/{beggining}/to/{destination}

ή ακόμα

/this/is/*/path/to/{somewhere}

Όλες οι μεταβλητές {variable} είναι προσβάσιμες από το annotation @PathVariable(“variable “) μέσα στον controller

Αν δοκιμάσουμε να το κάνουμε αυτό σε έναν τυπικό  VOID controller ΘΑ ΑΠΟΤΥΧΟΥΜΕ με μήνυμα τύπου file not found.

Ας δούμε γιατί και ας γυρίσουμε ένα controller σε Spring 3 with REST.

Ένας τυπικός controller στο Spring 2.5 είναι

[java]<br /><br />@RequestMapping(value = "/welcome",method = RequestMethod.GET)<br /><br />public ModelMap welcome(){<br /><br />logger.info("Accessing /welcome.html in ContentController");<br /><br />ModelMap map = new ModelMap();<br /><br />String myStr = "Hello ZENIKA HELLAS";<br /><br />map.addAttribute("myStr", myStr);<br /><br />return map;<br /><br />}[/java]

Ο Οποίος αναλύεται

@RequestMapping(value = “/welcome”,method = RequestMethod.GET)

Δέξου όλα τα request για το /welcome που είναι με μέθοδο GET.

ModelMap map = new ModelMap();

Φτιάξε ένα ModelMap με όνομα map

map.addAttribute(“myStr”, myStr);

Βάλε στο map τη φράση «Hello ZENIKA HELLAS» (τυχαια μου ήρθε στο μυαλό)

Και επέστρεψε το map

Όταν ο controller λοιπον έχει void μεθοδο mapped κάπου, τότε από default λέει στον viewResolver να βρεί το physical path για το αρχείο, δηλαδή επι του προκειμένου /welcome.jsp

Οπότε καταλαβαίνουμε ότι μπορεί να είχαμε ένα Uri mapping της μορφής /welcome/{user} αλλά θα έπρεπε να είχαμε για κάθε ένα πχ από τα παρακάτω

/welcome/alexis

/welcome/Joanna

Τα αντίστοιχα αρχεία

/welcome/alexis.jsp

/welcome/Joanna.jsp

Πράγμα που δε πολύ βολεύει 😀

Οπότε τι κάνουμε…

Γυρίζουμε τη μέθοδο σε String!

Όταν η μέθοδος είναι String τότε ο controller λέει στον viewResolver να βρει το αρχείο στο path που λέει η τιμή που επιστρέφει!

Δηλαδή

[java]<br /><br />@RequestMapping(value = "/welcome/{user}",method = RequestMethod.GET)<br /><br />public String welcome(){<br /><br />...<br /><br />Μπλα μπλα μπλα<br /><br />...<br /><br />return("/welcome");[/java]

όλα τα

/welcome/alexis

/welcome/Joanna

Τελικά θα καταλήγουν στο /welcome.jsp

Πώς όμως θα μπορώ να περνάω πράγματα στο view μου?

Θα πρέπει να ορίζω στη μέθοδο μια μεταβλητή τύπου Model. Το Spring με το που θα τη βλέπει θα την αρχικοποιεί και θα τη περνάει στο view μου.

Μετά λοιπόν από όλα αυτά το παράδειγμα μας γενικεύεται στο παρακάτω.

[java]<br /><br />@RequestMapping(value="/welcome/{user}", method=RequestMethod.GET)<br /><br />public String welcomeUser(@PathVariable("user") String user, Model model) {<br /><br />UserDetails ud = User.getDetails(user);<br /><br />model.addAttribute("userDetails", ud);<br /><br />return "/welcome";<br /><br />}[/java]

Content Negotiation

Στο Spring-MVC  2.5 ο @Controller αποφασίζει τι είδους view να κάνει render μέσα από τον. Σε ένα RESTful σενάριο, θα έπρεπε ο client να αποφασίσει μέσα από το Accept HTTP header

Εκεί χρησιμεύει ο ContentNegotiatingViewResolver. Κοιτάει το Accept header ή file extension από τους άλλους ViewResolvers και κάνει resolves ένα view ανάλογο.

To-Do…

Σύντομα θα γράψω ένα παράδειγμα για το πώς να φτιάξεις μια εφαρμογή που να παίζει με τα παραπάνω…

Passionate Archer, Runner, Linux lover and JAVA Geek! That's about everything! He has worked for many years as an Software Architect designing and developing enterprize projects, e-banking and high availability portals with extensive experience in the public, european and private sectors. Having speaker in several confrences he never misses opportunities to interact with the OSS community. In his leisure time he either runs or shoots a lot of arrows!