SlideShare una empresa de Scribd logo
1 de 31
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

Más contenido relacionado

La actualidad más candente

Слава Бобик «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 beginnersishan0019
 
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 184Mahmoud Samir Fayed
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz 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 & retrofitTed 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, KolGeneDroidConTLV
 
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 212Mahmoud 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 202Mahmoud 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 181Mahmoud Samir Fayed
 
Java 7 at SoftShake 2011
Java 7 at SoftShake 2011Java 7 at SoftShake 2011
Java 7 at SoftShake 2011julien.ponge
 
Java 7 JUG Summer Camp
Java 7 JUG Summer CampJava 7 JUG Summer Camp
Java 7 JUG Summer Campjulien.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
 

La actualidad más candente (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 a Jersey Guice AOP

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3Simon Su
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
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#9Ismar Silveira
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 
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
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 

Similar a 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
 
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
 
E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 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#
 

Más de 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
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 

Último (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

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

Notas del editor

  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