Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Creating modern java web applications based on struts2 and angularjs

5.802 Aufrufe

Veröffentlicht am

Slides from my talk about Struts2 with AngularJS at ApacheCon core 2015 in Budapest.

Content:
- Changes in the upcoming Struts 2.5 release
- How to start with Struts2 and AngularJS
- Use Struts2 REST Plugin for RESTfull actions
- How to manage exceptions in single page applications with AngularJS
- How to use bean validation in Struts2 applications
- Support for multi language

Example applications available at github.com:
https://github.com/apache/struts-examples/tree/master/rest-angular

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

Creating modern java web applications based on struts2 and angularjs

  1. 1. Creating Modern Java Web Applications Based on and ApacheCon: Core Europe 2015 by   ( )Johannes Geppert @jogep
  2. 2. About me Apache Member and Struts PMC Member Software Developer @  Living and working in Leipzig
  3. 3. About Struts2 Action based Java web framework Built upon a Request/Response cycle Clean architecture Easy to extend with plugins
  4. 4. Conceptual Overview
  5. 5. Struts 2.5 is on the way!
  6. 6. Cleanup and Maintenance! Switch to Java7 Increased Security with SMI xwork­core merged into struts­core Removal of deprecated plugins Dojo Plugin Code Behind Plugin JSF Plugin Struts1 Plugin
  7. 7. Support for bean validation Now as a (built­in) plugin available
  8. 8. Log4j2 as new Logging Layer Replacement for Struts2 Logging Layer Support for multiple logging implementations Better performance
  9. 9. Beta2 is available!
  10. 10. Why AngularJS?  AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML's syntax to express your application's components clearly and succinctly. Angular's data binding and dependency injection eliminate much of the code you would otherwise have to write. And it all happens within the browser, making it an ideal partner with any server technology. https://docs.angularjs.org/guide/introduction
  11. 11. AngularJS ­ Overview
  12. 12. Google Trends AngularJS, React, Backbone and ember.js Blue line is the trend for AngularJS
  13. 13. Quickstart with Maven Archetypes mvn archetype:generate ­B            ­DgroupId=com.mycompany.mysystem           ­DartifactId=myWebApp           ­DarchetypeGroupId=org.apache.struts           ­DarchetypeArtifactId=struts2­archetype­angularjs           ­DarchetypeVersion=<CURRENT_STRUTS_VERSION>           ­DremoteRepositories=http://struts.apache.org cd myWebApp mvn jetty:run Open Browser http://localhost:8080
  14. 14. REST Based Actions with Struts2 REST Plugin
  15. 15. REST ­ Action Mapping HTTP method URI Class.method Paramete GET /order OrderController.index   GET /order/1 OrderController.show id="1" POST /order OrderController.create   PUT /order/1 OrderController.update id="1" DELETE /order/1 OrderController.destroy id="1"
  16. 16. Configure the REST Plugin Add the rest plugin to the dependencies <dependency>   <groupId>org.apache.struts</groupId>   <artifactId>struts2­rest­plugin</artifactId>   <version>${struts2.version}</version> </dependency> Disable restrictToGET default behaviour <constant name="struts.rest.content.restrictToGET" value="false"/> Create packages for applications <constant name="struts.convention.default.parent.package"              value="rest­angular"/> <package name="rest­angular" extends="rest­default">     <default­action­ref name="index" /> </package> <package name="data" extends="rest­angular" namespace="/data"> </package>
  17. 17. REST ­ Content Type Handler /order/1 or /order/1.action Dispatcher (e.g. JSP) /order/1.xml XML Handler /order/1.json JSON Handler Easy to build e.g. for CSV result Built­in Jackson support for JSON serialization <bean type="org.apache.struts2.rest.handler.ContentTypeHandler"         name="jackson"         class="org.apache.struts2.rest.handler.JacksonLibHandler"/> <constant name="struts.rest.handlerOverride.json"         value="jackson"/>
  18. 18. Live Demo https://github.com/apache/struts­examples/tree/master/rest­ angular
  19. 19. Exception Handling
  20. 20. Custom Exception Interceptor protected String doIntercept(ActionInvocation actionInvocation)                             throws Exception {     try{         return actionInvocation.invoke();     } catch (Exception exception) {         Map<String, Object> errors = new HashMap<>();         HttpHeaders httpHeaders = new DefaultHttpHeaders()             .disableCaching().withStatus(HttpServletResponse.SC_BAD_REQUEST)                             .renderResult(Action.INPUT);         if(exception instanceof SecurityException) {             errors.put(ACTION_ERROR, "Operation not allowed!");             httpHeaders.setStatus(HttpServletResponse.SC_FORBIDDEN);         }  else { errors.put(ACTION_ERROR, exception.getMessage()); }         return manager.handleResult(actionInvocation.getProxy().getConfig(),                             httpHeaders, errors);     } }
  21. 21. Extend the Default Interceptor Stack <package name="data" extends="rest­angular" namespace="/data">     <interceptors>         <interceptor name="dataError"             class="....ExceptionHandlerInterceptor"/>         <interceptor­stack name="dataDefaultStack">             <interceptor­ref name="dataError"/>             <interceptor­ref name="restDefaultStack"/>         </interceptor­stack>     </interceptors>     <default­interceptor­ref name="dataDefaultStack"/> </package>
  22. 22. Dispatch an error event Extend the generic _request method in DataService $http(req).success(function(data) {     def.resolve(data); }).error(function(data, code) {     def.reject(data);     if(data.actionError) {         $rootScope.$emit('data­error', {  msg: data.actionError });     } });
  23. 23. Listen to error events e.g in a Controller $rootScope.$on('data­error', function(event, alert) {     console.log(alert.msg); });
  24. 24. Live Demo https://github.com/apache/struts­examples/tree/master/rest­ angular
  25. 25. Bean Validation Client and Server side New bean validation plugin
  26. 26. Setup bean validation
  27. 27. Specify a validation http status code like "Not Acceptable" <!­­ Set validation failure status code ­­> <constant name="struts.rest.validationFailureStatusCode" value="406"/>
  28. 28. Change rest interceptor stack Default validation interceptor is using the old validation interceptor Copy the rest default interceptor stack Define the new one <interceptor name="beanValidation"     class="....interceptor.BeanValidationInterceptor"/> Replace the "validation" reference with "beanValidation" reference in the stack
  29. 29. Live Demo https://github.com/apache/struts­examples/tree/master/rest­ angular
  30. 30. Multi­Language Support
  31. 31. Where do we need it? Frontend Validation Backend
  32. 32. Resource Bundles Split them up! <constant name="struts.custom.i18n.resources"                             value="frontend,validation,exceptions"/> Sample for validation messages #validation_en.properties validation.order.client = Client name can not be blank validation.order.amount = Order amount needs to be between 10 and 666 #validation_de.properties validation.order.client = Kunden Name darf nicht leer sein validation.order.amount = Anzahl muss zwischen 10 und 666 sein
  33. 33. Language Controller public class LanguageController extends RestActionSupport     implements ModelDriven<Map<String, String>> {     private Map<String, String> model;     public String index() throws Exception {         ResourceBundle bundle = getTexts("frontend");         this.model = bundle.keySet().stream()             .collect(Collectors.toMap(                 key ­> key, key ­> bundle::getString));         return Action.SUCCESS;     }     public Map<String, String> getModel() { return model; } }
  34. 34. Setup Angular Translate (function() { 'use strict'; angular .module('app', ['ngRoute', 'ui.bootstrap', 'pascalprecht.translate']); })(); $translateProvider.registerAvailableLanguageKeys(['en', 'de']); $translateProvider.fallbackLanguage('en'); $translateProvider.useUrlLoader('data/language.json', {     queryParameter: 'request_locale' }); $translateProvider.determinePreferredLanguage();
  35. 35. With translate filter in templates {{'order.client' | translate}} In validation messages @NotBlank(message = "validation.order.client") @Min(value = 10, message = "validation.order.amount") @Max(value = 666, message = "validation.order.amount") In java code throw new RuntimeException(getText("exception.not.supported"));
  36. 36. Live Demo https://github.com/apache/struts­examples/tree/master/rest­ angular
  37. 37. Thank you! https://twitter.com/jogep
  38. 38. Resources  ­   ­   ­   ­   ­  Apache Struts Project https://struts.apache.org Struts2 Maven Archetypes https://struts.apache.org/docs/struts­2­maven­archetypes.html Struts2 Examples https://github.com/apache/struts­examples AngularJS https://angularjs.org Angular Translate https://angular­translate.github.io
  39. 39. Attributions Leipzig Pictures by   by   by   by   by   by   by  Ruthe Cartoon by   by   by   by   by   by  Johannes Geppert Model in the wind tunnel DLR ­ German Aerospace Center Road Nicola Clean Up Allen Goldblatt Beans Matthew Matrix pills ThomasThomas Shaking Hands Aaron Gilson ruthe.de Language Scramble Eric Andresen Windows Box Perfection Rachel Kramer Krakow Door John Finn 1949 Ford Coupe ­ flat head V8 engine dave_7 Questions Alexander Henning Drachmann

×