SlideShare a Scribd company logo
Jersey + Guice + AOP




                Domenico Briganti
                dometec@gmail.com
Chi sono?
@PerRequest
public class Presentation {

    @GET
    @Path("/JugMilano/People/DomenicoBriganti")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUserDetails() {

     UserDetails userdet = new UserDetails();
     userdet.setCompany("Eidon srl");
     userdet.setEmail("dometec@gmail.com");
     userdet.setLinkedin("http://www.linkedin.com/in/dometec");
     userdet.setBlog("http://tipsaboutmywork.blogspot.com/");
     ...

    return Response.ok(userdet).build();

}


                                        JUG Milano – Meeting #48   2
Agenda
JAX-RS
Jersey con Guice/AOP

Demos:
Log delle richieste
Trim dei parametri Stringa in ingresso
Evitare chiamate identiche su un cluster
Transazioni
Login cookie


                               JUG Milano – Meeting #48   3
JAX-RS
Java API for RESTful Web Services
Release 1.1, JSR 311, 2009, JEE6 Full
Release futura 2.0, JSR 339, (EDR2 2012), JEE7
Package: javax.ws.rest
Implementazioni: Jersey (RI), Apache CXF,
  RESTEasy, Apache Wink




                              JUG Milano – Meeting #48   4
Jersey
Open source, RI for JAX-RS

Jersey 1.x (1.13b1) implements JAX-RS 1.1

Jersey 2.x (mileston 3) implements JAX-RS 2

CDDL + GPL 1.1




                              JUG Milano – Meeting #48   5
Jersey Hello World
import   javax.ws.rs.GET;
import   javax.ws.rs.Path;
import   javax.ws.rs.PathParam;
import   javax.ws.rs.core.Response;

@Path("/hello")
public class HelloWorldService {

          @GET
          @Path("/{param}")
          public Response getMsg(@PathParam("param") String msg) {

                  String output = "Echo: " + msg;
                  return Response.ok(output).build();

          }

}




                                             JUG Milano – Meeting #48   6
JAX-RS Annotation
Verbi HTTP: @GET, @POST, @PUT, @DELETE,
 @OPTION, @HEAD

Identificazione risorse: @Path

Input: @PathParam, @QueryParam, @MatrixParam,
  @HeaderParam, @CookieParam. @FormParam.
  @DefaultValue. MultivaluedMap<String, String>

Content negotiation: @Produces, @Consume


                                 JUG Milano – Meeting #48   7
JAX-RS Annotation e Facility
Ambiente: @Context (ServletConfig, ServletContext,
 HttpServletRequest, HttpServletResponse,
 SecurityContext, UriInfo, HttpHeaders)

Mapper, MessageBodyWriters,
 MessageBodyReaders: @Provider

ResponseBuilder e UriBuilder




                               JUG Milano – Meeting #48   8
DEMO 0

  “Esecuzione” della
slide di presentazione




                JUG Milano – Meeting #48   9
Jersey-Guice integration
           <listener>
               <listener-class>org.example.demo.GuiceConfig</listener-class>
           </listener>

           <filter>
               <filter-name>GuiceFilter</filter-name>
web.xml:
web.xml




               <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
           </filter>

           <filter-mapping>
               <filter-name>GuiceFilter</filter-name>
               <url-pattern>/services/*</url-pattern>
               <url-pattern>/application.wadl</url-pattern>
               <url-pattern>/application.wadl/*</url-pattern>
           </filter-mapping>

           package org.example.demo;

           public class GuiceConfig extends GuiceServletContextListener {

            @Override
listener




            protected Injector getInjector() {

              return Guice.createInjector(new JerseyServletModule() {
                @Override
                protected void configureServlets() {

                  Map<String, String> params = new HashMap<String, String>();

                  params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo");
                  params.put(ResourceConfig.FEATURE_TRACE, "true");
                  params.put(ResourceConfig.FEATURE_TRACE_PER_REQUEST, "true");
                  ...



                                                                                JUG Milano – Meeting #48   10
Demo 1

Log delle richieste




              JUG Milano – Meeting #48   11
Demo 1 – Log delle richieste (interc.)
public class LogCall implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {

        Logger logger = LoggerFactory.getLogger(invocation.getThis().getClass());

        String arg = Joiner.on(", ").useForNull("null").join(invocation.getArguments());
        logger.debug("{} ({}).", invocation.getMethod().getName(), arg);

        Object result = invocation.proceed();

        logger.trace("Output: {}.", result);

        return result;

    }

}




                                                       JUG Milano – Meeting #48        12
Demo 1 – Log delle richieste (bind)
public class GuiceConfig extends GuiceServletContextListener {

 @Override
 protected Injector getInjector() {

   return Guice.createInjector(new JerseyServletModule() {

     @Override
     protected void configureServlets() {

       Map<String, String> params = new HashMap<String, String>();

       params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo");
       ...

       filter("/*").through(GuiceContainer.class, params);

       install(new Module() {

         public void configure(Binder binder) {

           LogCall logCall = new LogCall();
           TrimAndNullInterceptor trimAndNullableInterceptor = new TrimAndNullInterceptor();

           bindInterceptor(
           Matchers.annotatedWith(Path.class),
           Matchers.annotatedWith(GET.class).or(Matchers.annotatedWith(POST.class))
           .or(Matchers.annotatedWith(PUT.class)).or(Matchers.annotatedWith(DELETE.class)),
           trimAndNullableInterceptor, logCall);




                                                             JUG Milano – Meeting #48          13
Demo 2 – Trim parametri (interc.)
public class TrimAndNullInterceptor implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {

        for (int i = 0; i < invocation.getArguments().length; i++) {

            if (invocation.getArguments()[i] != null &&
                invocation.getArguments()[i] instanceof String) {

                 String sparam = (String) invocation.getArguments()[i];

                 String trim = sparam.trim();

                 if (trim.isEmpty())
                      invocation.getArguments()[i] = null;
                 else
                      invocation.getArguments()[i] = trim;
        }

    }

    return invocation.proceed();

    }
}




                                                        JUG Milano – Meeting #48   14
Demo 2 – Trim parametri (bind)
public class GuiceConfig extends GuiceServletContextListener {

 @Override
 protected Injector getInjector() {

   return Guice.createInjector(new JerseyServletModule() {

     @Override
     protected void configureServlets() {

       Map<String, String> params = new HashMap<String, String>();

       params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo");
       ...

       filter("/*").through(GuiceContainer.class, params);

       install(new Module() {

         public void configure(Binder binder) {

           LogCall logCall = new LogCall();
           TrimAndNullInterceptor trimAndNullableInterceptor = new TrimAndNullInterceptor();

           bindInterceptor(
           Matchers.annotatedWith(Path.class),
           Matchers.annotatedWith(GET.class).or(Matchers.annotatedWith(POST.class))
           .or(Matchers.annotatedWith(PUT.class)).or(Matchers.annotatedWith(DELETE.class)),
           trimAndNullableInterceptor, logCall);




                                                             JUG Milano – Meeting #48          15
Evitare richieste duplicate
Problemi:
  Ristrasmissioni
  Doppi submit (anche Tripli...) da browser
  Timeout lato client che scatena altre prove di richieste


Rimedi:
  Hashtable con chiamate attualmente in corso
  429 Too Many Requests (RFC 6585)
  Infinispan con lock condiviso per sistemi cluster



                                     JUG Milano – Meeting #48   16
Demo 3 – Richieste duplicate (uso)
@POST
@UniqueCallOnCluster
public Response getAccountBalance(@FormParam("fromuser")...


@POST
@UniqueCallOnCluster
public Response getAccountBalance(@KeyParameter
@FormParam("fromuser")...




                                      JUG Milano – Meeting #48   17
Demo 3 – Richieste duplicate (Inter.)
public class UniqueCallOnClusterInterceptor implements MethodInterceptor {
   ...
   public Object invoke(MethodInvocation invocation) throws Throwable {

     String classname = invocation.getMethod().getDeclaringClass().getSimpleName();
     String methodName = invocation.getMethod().getName();
     String key = classname + "_" + methodName + "_" + extractParameterValue(invocation);

     TransactionManager tm = keyCallOnClusterService.getTransactionManager();

     tm.begin();
     boolean success = keyCallOnClusterService.lock(key);

     if (!success) {
          logger.info("Non posso effettuare il lock sul cluster per la chiave {}.", key);
          return Response.status(429).entity("Another call with same parameter is in progress.").build();
     }

     String runningServer = (String) keyCallOnClusterService.get(key);
     if (runningServer != null) {
          logger.info("Chiamata già in corso, server {}.", runningServer);
          return Response.status(429).entity("Another call with same parameter is in progress.").build();
     }

     keyCallOnClusterService.put(key, "todo-hostname");
     tm.commit();
     ...
     return invocation.proceed();
     ...

     keyCallOnClusterService.remove(key);

}



                                                                JUG Milano – Meeting #48               18
Demo 3 – Richieste duplicate (bind)
public class GuiceConfig extends GuiceServletContextListener {

 @Override
 protected Injector getInjector() {

   return Guice.createInjector(new JerseyServletModule() {

     @Override
     protected void configureServlets() {

       Map<String, String> params = new HashMap<String, String>();

       params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo");
       ...

       filter("/*").through(GuiceContainer.class, params);

       install(new Module() {

         public void configure(Binder binder) {

             UniqueCallOnClusterInterceptor uniqueCallOnClusterInterceptor =
                  new UniqueCallOnClusterInterceptor();
             requestInjection(uniqueCallOnClusterInterceptor);
             bindInterceptor(Matchers.any(), Matchers.annotatedWith(UniqueCallOnCluster.class),
                  uniqueCallOnClusterInterceptor);




                                                             JUG Milano – Meeting #48         19
Transazioni con AOP




             JUG Milano – Meeting #48   20
Transazioni con AOP




             JUG Milano – Meeting #48   21
Transazioni con AOP




             JUG Milano – Meeting #48   22
Demo 4 – Transazioni (uso)
package org.example.demo.controller;


@PerRequest
@Transactional
@Path("services/transactionalresource3")
public class TransactionalResource3Write extends AbstractTransactionalResource {

   @Inject
   public TransactionalResource3Write() {
   }

   @POST
   @Produces("text/plain")
   public String get() {

   ...

                                                  JUG Milano – Meeting #48         23
Demo 4 – Transazioni (uso)
package org.example.demo.controller;

@PerRequest
@Transactional(TransactionType.ReadOnly)
@Path("services/transactionalresource1")
public class TransactionalResource1ReadOnly extends AbstractTransactionalResource {

    @Inject
    public TransactionalResource1ReadOnly() {
    }

    @GET
    @Produces("text/plain")
    @SuppressWarnings("unchecked")
    public String get() {

        List<DatabaseLog> list = getSession().createCriteria(DatabaseLog.class).list();

        if (list.size() == 0)
              return "No record!";
                                                         JUG Milano – Meeting #48         24
Demo 4 – Transazioni (uso)
package org.example.demo.controller;

@PerRequest
@Transactional(TransactionType.RequiredNew)
@Path("services/transactionalresource5")
public class TransactionalResource5ReqNew extends AbstractTransactionalResource {

    @Inject
    public TransactionalResource5ReqNew() {
    }

    ...




                                                      JUG Milano – Meeting #48      25
Demo 4 – Transazioni (uso)
public abstract class AbstractTransactionalResource {
   private Session session;

    @NoTransactional
    public void setSession(Session session) {
       this.session = session;              }

    @NoTransactional
    public Session getSession()             {
       return session;                      }

    @Override
    @NoTransactional
    protected void finalize() throws Throwable {
        super.finalize();                      }

}
                                                   JUG Milano – Meeting #48   26
Demo 4 – Transazioni 1/2 (interc.)
public class TransactionInterceptor implements MethodInterceptor {

     private final ThreadLocal<Stack<Session>> sessionThreadLocal;

          public Object invoke(MethodInvocation invocation) throws Throwable {
               ...
               Transactional transactional =
invocation.getMethod().getDeclaringClass().getAnnotation(Transactional.class);
               ...

               Stack<Session> sessionStack = sessionThreadLocal.get();
               Transaction transaction = null;
               Session session = null;
               if (!sessionStack.isEmpty())
                    session = sessionStack.peek();

               if (session == null || transType.equals(TransactionType.RequiredNew)) {

                    boolean readonly = false;
                    readonly = transType.equals(TransactionType.ReadOnly);
                    session = hibernateSessionService.openSession(readonly);
                    transaction = session.getTransaction();
                    transaction.begin();
                    sessionStack.push(session);
               }

               Session oldSession = null;
               AbstractTransactionalResource service = ((AbstractTransactionalResource)
invocation.getThis());
               oldSession = service.getSession();
               service.setSession(session);

               Object result = invocation.proceed();



                                                                JUG Milano – Meeting #48   27
Demo 4 – Transazioni 2/2 (interc.)
         try {

              Object result = invocation.proceed();

              if (transaction != null) {
                   session.flush();
                   transaction.commit();
              }

              return result;

         } catch (Exception e) {

              transaction.rollback();
              throw e;

         } finally {

              if (transaction != null) {
                   hibernateSessionService.closeSession(session);
                   sessionStack.pop();
                   if (sessionStack.isEmpty())
                        sessionThreadLocal.remove();
              }

              service.setSession(oldSession);

         }

    }

}




                                                               JUG Milano – Meeting #48   28
Demo 4 – Transazioni (bind)
public class GuiceConfig extends GuiceServletContextListener {

 @Override
 protected Injector getInjector() {

   return Guice.createInjector(new JerseyServletModule() {

     @Override
     protected void configureServlets() {

       Map<String, String> params = new HashMap<String, String>();

       params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo");
       ...

       filter("/*").through(GuiceContainer.class, params);

       install(new Module() {

         public void configure(Binder binder) {

           TransactionInterceptor transactionInterceptor =
             new TransactionInterceptor();
           requestInjection(transactionInterceptor);
           bindInterceptor(Matchers.annotatedWith(Transactional.class),
             Matchers.not(Matchers.annotatedWith(NoTransactional.class)),
             TransactionInterceptor);




                                                             JUG Milano – Meeting #48   29
Demo 5 - Login Cookie (bind)
Annotation:
  AuthenticatedUser
  ApplicationRolesAllowed
Provider:
  AuthenticatedUserProvider
Exception e ExceptionMapper:
  NotAuthenticatedException(+Mapper)
  NotAuthorizedException(+Mapper)
Cookie: LoginCookieManager
Utente: DemoPrincipal
Interceptor: ApplicationRolesAllowedInterceptor
                                JUG Milano – Meeting #48   30
Grazie!

Domande??




Riferimenti:
http://jersey.java.net
http://code.google.com/p/google-guice/
Demo webapp:
 https://github.com/dometec/shadedcode/tree/master/demo-webapp




                                         JUG Milano – Meeting #48   31

More Related Content

What's hot

Guice2.0
Guice2.0Guice2.0
Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»
SpbDotNet Community
 
Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical FileSoumya Behera
 
망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19종인 전
 
Java practice programs for beginners
Java practice programs for beginnersJava practice programs for beginners
Java practice programs for beginners
ishan0019
 
The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184
Mahmoud Samir Fayed
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
Fiyaz Hasan
 
#5 (Remote Method Invocation)
#5 (Remote Method Invocation)#5 (Remote Method Invocation)
#5 (Remote Method Invocation)
Ghadeer AlHasan
 
Dagger & rxjava & retrofit
Dagger & rxjava & retrofitDagger & rxjava & retrofit
Dagger & rxjava & retrofit
Ted Liang
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
DroidConTLV
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212
Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 13 of 181
The Ring programming language version 1.5.2 book - Part 13 of 181The Ring programming language version 1.5.2 book - Part 13 of 181
The Ring programming language version 1.5.2 book - Part 13 of 181
Mahmoud Samir Fayed
 
Java 7 at SoftShake 2011
Java 7 at SoftShake 2011Java 7 at SoftShake 2011
Java 7 at SoftShake 2011julien.ponge
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
Guido Pio Mariotti
 
Java 7 JUG Summer Camp
Java 7 JUG Summer CampJava 7 JUG Summer Camp
Java 7 JUG Summer Camp
julien.ponge
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2Technopark
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 

What's hot (20)

Guice2.0
Guice2.0Guice2.0
Guice2.0
 
Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»
 
Advanced Java Practical File
Advanced Java Practical FileAdvanced Java Practical File
Advanced Java Practical File
 
京都Gtugコンパチapi
京都Gtugコンパチapi京都Gtugコンパチapi
京都Gtugコンパチapi
 
망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19망고100 보드로 놀아보자 19
망고100 보드로 놀아보자 19
 
Spock and Geb in Action
Spock and Geb in ActionSpock and Geb in Action
Spock and Geb in Action
 
Java practice programs for beginners
Java practice programs for beginnersJava practice programs for beginners
Java practice programs for beginners
 
The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184The Ring programming language version 1.5.3 book - Part 78 of 184
The Ring programming language version 1.5.3 book - Part 78 of 184
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
#5 (Remote Method Invocation)
#5 (Remote Method Invocation)#5 (Remote Method Invocation)
#5 (Remote Method Invocation)
 
Dagger & rxjava & retrofit
Dagger & rxjava & retrofitDagger & rxjava & retrofit
Dagger & rxjava & retrofit
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202
 
The Ring programming language version 1.5.2 book - Part 13 of 181
The Ring programming language version 1.5.2 book - Part 13 of 181The Ring programming language version 1.5.2 book - Part 13 of 181
The Ring programming language version 1.5.2 book - Part 13 of 181
 
Java 7 at SoftShake 2011
Java 7 at SoftShake 2011Java 7 at SoftShake 2011
Java 7 at SoftShake 2011
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
 
Java 7 JUG Summer Camp
Java 7 JUG Summer CampJava 7 JUG Summer Camp
Java 7 JUG Summer Camp
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 

Similar to Jersey Guice AOP

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
javatwo2011
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
Ignacio Coloma
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
Simon Su
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
MongoDB
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9
Ismar Silveira
 
Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9
Ismar Silveira
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
Ankit Rastogi
 
Testing in android
Testing in androidTesting in android
Testing in android
jtrindade
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、GaelykでハンズオンTsuyoshi Yamamoto
 
Struts2 notes
Struts2 notesStruts2 notes
Struts2 notes
Rajiv Gupta
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Introduccion a AspectJ
Introduccion a AspectJIntroduccion a AspectJ
Introduccion a AspectJ
Mauricio Quezada
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Diifeerences In C#
Diifeerences In C#Diifeerences In C#
Diifeerences In C#
rohit_gupta_mrt
 

Similar to Jersey Guice AOP (20)

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9
 
Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Testing in android
Testing in androidTesting in android
Testing in android
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
 
Struts2 notes
Struts2 notesStruts2 notes
Struts2 notes
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Introduccion a AspectJ
Introduccion a AspectJIntroduccion a AspectJ
Introduccion a AspectJ
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Diifeerences In C#
Diifeerences In C#Diifeerences In C#
Diifeerences In C#
 

More from Domenico Briganti

Software Testing e TDD
Software Testing e TDDSoftware Testing e TDD
Software Testing e TDD
Domenico Briganti
 
Xml annessi e connessi
Xml annessi e connessiXml annessi e connessi
Xml annessi e connessi
Domenico Briganti
 
Xml Xslt
Xml  XsltXml  Xslt

More from Domenico Briganti (8)

Software Testing e TDD
Software Testing e TDDSoftware Testing e TDD
Software Testing e TDD
 
XSLT
XSLT XSLT
XSLT
 
XSL-FO
XSL-FOXSL-FO
XSL-FO
 
XML Schema (XSD)
XML Schema (XSD)XML Schema (XSD)
XML Schema (XSD)
 
Xml annessi e connessi
Xml annessi e connessiXml annessi e connessi
Xml annessi e connessi
 
Java codestyle & tipstricks
Java codestyle & tipstricksJava codestyle & tipstricks
Java codestyle & tipstricks
 
Testing
TestingTesting
Testing
 
Xml Xslt
Xml  XsltXml  Xslt
Xml Xslt
 

Recently uploaded

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.
ViralQR
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
Vlad Stirbu
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 

Recently uploaded (20)

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 

Jersey Guice AOP

  • 1. Jersey + Guice + AOP Domenico Briganti dometec@gmail.com
  • 2. Chi sono? @PerRequest public class Presentation { @GET @Path("/JugMilano/People/DomenicoBriganti") @Produces(MediaType.APPLICATION_JSON) public Response getUserDetails() { UserDetails userdet = new UserDetails(); userdet.setCompany("Eidon srl"); userdet.setEmail("dometec@gmail.com"); userdet.setLinkedin("http://www.linkedin.com/in/dometec"); userdet.setBlog("http://tipsaboutmywork.blogspot.com/"); ... return Response.ok(userdet).build(); } JUG Milano – Meeting #48 2
  • 3. Agenda JAX-RS Jersey con Guice/AOP Demos: Log delle richieste Trim dei parametri Stringa in ingresso Evitare chiamate identiche su un cluster Transazioni Login cookie JUG Milano – Meeting #48 3
  • 4. JAX-RS Java API for RESTful Web Services Release 1.1, JSR 311, 2009, JEE6 Full Release futura 2.0, JSR 339, (EDR2 2012), JEE7 Package: javax.ws.rest Implementazioni: Jersey (RI), Apache CXF, RESTEasy, Apache Wink JUG Milano – Meeting #48 4
  • 5. Jersey Open source, RI for JAX-RS Jersey 1.x (1.13b1) implements JAX-RS 1.1 Jersey 2.x (mileston 3) implements JAX-RS 2 CDDL + GPL 1.1 JUG Milano – Meeting #48 5
  • 6. Jersey Hello World import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Response; @Path("/hello") public class HelloWorldService { @GET @Path("/{param}") public Response getMsg(@PathParam("param") String msg) { String output = "Echo: " + msg; return Response.ok(output).build(); } } JUG Milano – Meeting #48 6
  • 7. JAX-RS Annotation Verbi HTTP: @GET, @POST, @PUT, @DELETE, @OPTION, @HEAD Identificazione risorse: @Path Input: @PathParam, @QueryParam, @MatrixParam, @HeaderParam, @CookieParam. @FormParam. @DefaultValue. MultivaluedMap<String, String> Content negotiation: @Produces, @Consume JUG Milano – Meeting #48 7
  • 8. JAX-RS Annotation e Facility Ambiente: @Context (ServletConfig, ServletContext, HttpServletRequest, HttpServletResponse, SecurityContext, UriInfo, HttpHeaders) Mapper, MessageBodyWriters, MessageBodyReaders: @Provider ResponseBuilder e UriBuilder JUG Milano – Meeting #48 8
  • 9. DEMO 0 “Esecuzione” della slide di presentazione JUG Milano – Meeting #48 9
  • 10. Jersey-Guice integration <listener> <listener-class>org.example.demo.GuiceConfig</listener-class> </listener> <filter> <filter-name>GuiceFilter</filter-name> web.xml: web.xml <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>GuiceFilter</filter-name> <url-pattern>/services/*</url-pattern> <url-pattern>/application.wadl</url-pattern> <url-pattern>/application.wadl/*</url-pattern> </filter-mapping> package org.example.demo; public class GuiceConfig extends GuiceServletContextListener { @Override listener protected Injector getInjector() { return Guice.createInjector(new JerseyServletModule() { @Override protected void configureServlets() { Map<String, String> params = new HashMap<String, String>(); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo"); params.put(ResourceConfig.FEATURE_TRACE, "true"); params.put(ResourceConfig.FEATURE_TRACE_PER_REQUEST, "true"); ... JUG Milano – Meeting #48 10
  • 11. Demo 1 Log delle richieste JUG Milano – Meeting #48 11
  • 12. Demo 1 – Log delle richieste (interc.) public class LogCall implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { Logger logger = LoggerFactory.getLogger(invocation.getThis().getClass()); String arg = Joiner.on(", ").useForNull("null").join(invocation.getArguments()); logger.debug("{} ({}).", invocation.getMethod().getName(), arg); Object result = invocation.proceed(); logger.trace("Output: {}.", result); return result; } } JUG Milano – Meeting #48 12
  • 13. Demo 1 – Log delle richieste (bind) public class GuiceConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new JerseyServletModule() { @Override protected void configureServlets() { Map<String, String> params = new HashMap<String, String>(); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo"); ... filter("/*").through(GuiceContainer.class, params); install(new Module() { public void configure(Binder binder) { LogCall logCall = new LogCall(); TrimAndNullInterceptor trimAndNullableInterceptor = new TrimAndNullInterceptor(); bindInterceptor( Matchers.annotatedWith(Path.class), Matchers.annotatedWith(GET.class).or(Matchers.annotatedWith(POST.class)) .or(Matchers.annotatedWith(PUT.class)).or(Matchers.annotatedWith(DELETE.class)), trimAndNullableInterceptor, logCall); JUG Milano – Meeting #48 13
  • 14. Demo 2 – Trim parametri (interc.) public class TrimAndNullInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { for (int i = 0; i < invocation.getArguments().length; i++) { if (invocation.getArguments()[i] != null && invocation.getArguments()[i] instanceof String) { String sparam = (String) invocation.getArguments()[i]; String trim = sparam.trim(); if (trim.isEmpty()) invocation.getArguments()[i] = null; else invocation.getArguments()[i] = trim; } } return invocation.proceed(); } } JUG Milano – Meeting #48 14
  • 15. Demo 2 – Trim parametri (bind) public class GuiceConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new JerseyServletModule() { @Override protected void configureServlets() { Map<String, String> params = new HashMap<String, String>(); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo"); ... filter("/*").through(GuiceContainer.class, params); install(new Module() { public void configure(Binder binder) { LogCall logCall = new LogCall(); TrimAndNullInterceptor trimAndNullableInterceptor = new TrimAndNullInterceptor(); bindInterceptor( Matchers.annotatedWith(Path.class), Matchers.annotatedWith(GET.class).or(Matchers.annotatedWith(POST.class)) .or(Matchers.annotatedWith(PUT.class)).or(Matchers.annotatedWith(DELETE.class)), trimAndNullableInterceptor, logCall); JUG Milano – Meeting #48 15
  • 16. Evitare richieste duplicate Problemi: Ristrasmissioni Doppi submit (anche Tripli...) da browser Timeout lato client che scatena altre prove di richieste Rimedi: Hashtable con chiamate attualmente in corso 429 Too Many Requests (RFC 6585) Infinispan con lock condiviso per sistemi cluster JUG Milano – Meeting #48 16
  • 17. Demo 3 – Richieste duplicate (uso) @POST @UniqueCallOnCluster public Response getAccountBalance(@FormParam("fromuser")... @POST @UniqueCallOnCluster public Response getAccountBalance(@KeyParameter @FormParam("fromuser")... JUG Milano – Meeting #48 17
  • 18. Demo 3 – Richieste duplicate (Inter.) public class UniqueCallOnClusterInterceptor implements MethodInterceptor { ... public Object invoke(MethodInvocation invocation) throws Throwable { String classname = invocation.getMethod().getDeclaringClass().getSimpleName(); String methodName = invocation.getMethod().getName(); String key = classname + "_" + methodName + "_" + extractParameterValue(invocation); TransactionManager tm = keyCallOnClusterService.getTransactionManager(); tm.begin(); boolean success = keyCallOnClusterService.lock(key); if (!success) { logger.info("Non posso effettuare il lock sul cluster per la chiave {}.", key); return Response.status(429).entity("Another call with same parameter is in progress.").build(); } String runningServer = (String) keyCallOnClusterService.get(key); if (runningServer != null) { logger.info("Chiamata già in corso, server {}.", runningServer); return Response.status(429).entity("Another call with same parameter is in progress.").build(); } keyCallOnClusterService.put(key, "todo-hostname"); tm.commit(); ... return invocation.proceed(); ... keyCallOnClusterService.remove(key); } JUG Milano – Meeting #48 18
  • 19. Demo 3 – Richieste duplicate (bind) public class GuiceConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new JerseyServletModule() { @Override protected void configureServlets() { Map<String, String> params = new HashMap<String, String>(); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo"); ... filter("/*").through(GuiceContainer.class, params); install(new Module() { public void configure(Binder binder) { UniqueCallOnClusterInterceptor uniqueCallOnClusterInterceptor = new UniqueCallOnClusterInterceptor(); requestInjection(uniqueCallOnClusterInterceptor); bindInterceptor(Matchers.any(), Matchers.annotatedWith(UniqueCallOnCluster.class), uniqueCallOnClusterInterceptor); JUG Milano – Meeting #48 19
  • 20. Transazioni con AOP JUG Milano – Meeting #48 20
  • 21. Transazioni con AOP JUG Milano – Meeting #48 21
  • 22. Transazioni con AOP JUG Milano – Meeting #48 22
  • 23. Demo 4 – Transazioni (uso) package org.example.demo.controller; @PerRequest @Transactional @Path("services/transactionalresource3") public class TransactionalResource3Write extends AbstractTransactionalResource { @Inject public TransactionalResource3Write() { } @POST @Produces("text/plain") public String get() { ... JUG Milano – Meeting #48 23
  • 24. Demo 4 – Transazioni (uso) package org.example.demo.controller; @PerRequest @Transactional(TransactionType.ReadOnly) @Path("services/transactionalresource1") public class TransactionalResource1ReadOnly extends AbstractTransactionalResource { @Inject public TransactionalResource1ReadOnly() { } @GET @Produces("text/plain") @SuppressWarnings("unchecked") public String get() { List<DatabaseLog> list = getSession().createCriteria(DatabaseLog.class).list(); if (list.size() == 0) return "No record!"; JUG Milano – Meeting #48 24
  • 25. Demo 4 – Transazioni (uso) package org.example.demo.controller; @PerRequest @Transactional(TransactionType.RequiredNew) @Path("services/transactionalresource5") public class TransactionalResource5ReqNew extends AbstractTransactionalResource { @Inject public TransactionalResource5ReqNew() { } ... JUG Milano – Meeting #48 25
  • 26. Demo 4 – Transazioni (uso) public abstract class AbstractTransactionalResource { private Session session; @NoTransactional public void setSession(Session session) { this.session = session; } @NoTransactional public Session getSession() { return session; } @Override @NoTransactional protected void finalize() throws Throwable { super.finalize(); } } JUG Milano – Meeting #48 26
  • 27. Demo 4 – Transazioni 1/2 (interc.) public class TransactionInterceptor implements MethodInterceptor { private final ThreadLocal<Stack<Session>> sessionThreadLocal; public Object invoke(MethodInvocation invocation) throws Throwable { ... Transactional transactional = invocation.getMethod().getDeclaringClass().getAnnotation(Transactional.class); ... Stack<Session> sessionStack = sessionThreadLocal.get(); Transaction transaction = null; Session session = null; if (!sessionStack.isEmpty()) session = sessionStack.peek(); if (session == null || transType.equals(TransactionType.RequiredNew)) { boolean readonly = false; readonly = transType.equals(TransactionType.ReadOnly); session = hibernateSessionService.openSession(readonly); transaction = session.getTransaction(); transaction.begin(); sessionStack.push(session); } Session oldSession = null; AbstractTransactionalResource service = ((AbstractTransactionalResource) invocation.getThis()); oldSession = service.getSession(); service.setSession(session); Object result = invocation.proceed(); JUG Milano – Meeting #48 27
  • 28. Demo 4 – Transazioni 2/2 (interc.) try { Object result = invocation.proceed(); if (transaction != null) { session.flush(); transaction.commit(); } return result; } catch (Exception e) { transaction.rollback(); throw e; } finally { if (transaction != null) { hibernateSessionService.closeSession(session); sessionStack.pop(); if (sessionStack.isEmpty()) sessionThreadLocal.remove(); } service.setSession(oldSession); } } } JUG Milano – Meeting #48 28
  • 29. Demo 4 – Transazioni (bind) public class GuiceConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new JerseyServletModule() { @Override protected void configureServlets() { Map<String, String> params = new HashMap<String, String>(); params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "org.example.demo"); ... filter("/*").through(GuiceContainer.class, params); install(new Module() { public void configure(Binder binder) { TransactionInterceptor transactionInterceptor = new TransactionInterceptor(); requestInjection(transactionInterceptor); bindInterceptor(Matchers.annotatedWith(Transactional.class), Matchers.not(Matchers.annotatedWith(NoTransactional.class)), TransactionInterceptor); JUG Milano – Meeting #48 29
  • 30. Demo 5 - Login Cookie (bind) Annotation: AuthenticatedUser ApplicationRolesAllowed Provider: AuthenticatedUserProvider Exception e ExceptionMapper: NotAuthenticatedException(+Mapper) NotAuthorizedException(+Mapper) Cookie: LoginCookieManager Utente: DemoPrincipal Interceptor: ApplicationRolesAllowedInterceptor JUG Milano – Meeting #48 30

Editor's Notes

  1. Rel 1.1 Goals: POJO-based, HTTP-centric, Format Independence, Container Independence, Inclusion in Java EE. La release 2.0 si focalizza su HATEOAS e implementazioni client, ma anche su Validation, MVC, Async, Filters/Handlers, migliorie al Content Negotiation. Attualmente Early Draft Review 2.
  2. @FormParam is slightly special because it extracts information from a request representation that is of the MIME media type &amp;quot;application/x-www-form-urlencoded&amp;quot;
  3. Listener per la configurazione dell&apos;injector (bind,AOP). Filter per il processing delle richieste.
  4. Il log delle richieste già lo abbiamo sul access log del nostro webserver o application server. Ma per quanto riquarda il body in POST o PUT non ci viene in aiuto. Con questo Interceptor possiamo loggare sul nostro file applicativo le richieste che arrivano con tutti i parametri in input e il THREAD che evade la chiamata
  5. RFC6585: Additional HTTP Status Codes, April 2012, tra le altre cose: 3. 428 Precondition 4. 429 Too Many Requests 5. 431 Request Header Fields Too Large 6. 511 Network Authentication Required
  6. Come si usa