środa, 16 lutego 2011

Wicket+Atom

Tak na szybko... przy pomocy Xstream'a

1. Klasa, na podstawie której generowany będzie feed:

    @XStreamAlias("rss")  
    public class Atom {  
        @XStreamAsAttribute  
        @XStreamAlias("xmlns:atom")  
        String xmlns="http://www.w3.org/2005/Atom";  
        @XStreamAsAttribute  
        String version="2.0";  
        public channel channel=new channel();  
          
        public static class channel {  
           public String title;  
           public String subtitle;  
           public String link;  
           @XStreamAlias("atom:link")  
           public AtomLink atomLink;  
           public String language;  
           public Date lastBuildDate;  

           @XStreamImplicit(itemFieldName = "item")  
             public List entries=new ArrayList();  
          }  
          public static class AtomLink {  
             @XStreamAsAttribute  
             public String href;  
             @XStreamAsAttribute  
             public String rel="self";  
          }  
          public static class Entry {  
             public String title;  
             public String link;  
             public String description;  
             public Date pubDate;  
          }  
     }  
2. Wicket WebResource class:
   public class AtomWebResource extends WebResource {  
       public static Logger log = LoggerFactory.getLogger(AtomWebResource.class);  
       
      @Override  
      protected int getCacheDuration() {  
          return 0;  
      }  
         
      @Override  
      public IResourceStream getResourceStream() {  
          return new AbstractResourceStreamWriter() {  
              public String getContentType() {  
                  return "text/xml; charset=UTF-8";  
              }  
              public void write(OutputStream output) {  
                  try {  
                      BufferedWriter bufferedWriter = new BufferedWriter(new PrintWriter(output));               
                      bufferedWriter.write(getAtom());  
                      bufferedWriter.flush();  
                      bufferedWriter.close();  
                  } catch (IOException e) {  
                      log.error("",e);  
                  }                    
              }              
          };  
      }  
     // w celu optymalizacji, zamiast tworzyć feeda na nowo można go cache'ować   
     private String getAtom() {  
          Atom a=new Atom();  
        a.title="Tytul";
        //... tu wypełniamy wszystkie entry
        return xstream.toXML();
   }
} 
3. Dodanie resource do aplikacji Wicket
public void init() {
    getSharedResources().add(AtomWebResource.class.getName(), new AtomWebResource());
    mountSharedResource("feed", Application.class.getName()+"/"+AtomWebResource.class.getName());           
}
4. Dodanie linkow na stronach
  add(new ResourceLink("rssLink",new ResourceReference(AtomWebResource.class.getName())));
...i w html
       

sobota, 12 lutego 2011

Łączenie z zabezpieczonym WebService z klienta Javy

... a dokładniej łączenie z WebService opartą na EJB przy pomocy loginu i hasła. Jeśli chcemy wykorzystać certyfikaty cała procedura będzie wyglądała całkiem podobnie.

  1. Aplikacja: Nasza usługa powinna mieć annotacje @WebContext z authMethod="BASIC"
@WebService
@Stateless
@WebContext(contextRoot = "ws", authMethod = "BASIC")
public class MyService implements IMyService {

    @Resource
    private SessionContext ctx;
   
    public void foo() {
         String userLogin = ctx.getCallerPrincipal().getName();
         // dostep do loginu
    }
}



   2.  Aplikacja: META-INF/jboss.xml powinien zawierać definicję security domain, wykorzystane zostanie jaas
java:/jaas/MySecurityDomain 

  3.  Serwer: conf/login-config.xml powinien zawierać definicję security domain. W tym wypadku jest to najprostsze z możliwych logowanie przy pomocy user.properties i roles.properties

  
    
    
  


w login-config

  4.  Serwer: w conf powinny znajdować się pliki user.properties i roles.properties, kolejno:
username1=password1
username2=password2

username1=administrator
username2=operator 


Voila! Tyle po stronie serwera. Po stronie aplikacji klienckiej musimy dodać credentiale przed połączeniem się z usługą sieciową. Zakładam, że klient usługi został wygenerowany przez wsimport (albo jakoś tak) JBossa. Robi się to tak:

        import javax.xml.ws.BindingProvider;
        //....
        MyServiceService port = new  MyServiceService();
        IMyService myService = port.getMyServicePort();
        Map requestContext = ((BindingProvider)myService).getRequestContext();
        requestContext.put(BindingProvider.USERNAME_PROPERTY, "username1");
        requestContext.put(BindingProvider.PASSWORD_PROPERTY, "password1");
        myService.foo(); // autoryzowana metoda