Τα τελευταία χρόνια, το έχει γίνει η ντε φάκτο εναλλακτική λύση αντί για τις 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…
Σύντομα θα γράψω ένα παράδειγμα για το πώς να φτιάξεις μια εφαρμογή που να παίζει με τα παραπάνω…