Avatar billede speder Nybegynder
09. april 2003 - 07:08 Der er 17 kommentarer og
1 løsning

kalde en webservice i ren jsp

Hej

Jeg vil gerne kalde en webservice i ren jsp-kode. Jeg giver points til den som kan levere en fiks og færdig kode som fungerer med f.eks. følgende:

http://www.swanandmokashi.com/HomePage/WebServices/StockQuotes.asmx?WSDL 

M.v.h.

Søren
Avatar billede speder Nybegynder
09. april 2003 - 07:08 #1
Lige en tilføjelse - den skal kalde ovenstående og returnere aktieindex for f.eks. CTXS.
Avatar billede arne_v Ekspert
09. april 2003 - 07:20 #2
Jeg håber det er OK med Java kode i <% %> og et par support klasser ?
Avatar billede arne_v Ekspert
09. april 2003 - 08:56 #3
JSP fragmenter:

<%@ page import="com.swanandmokashi.*" %>

<TABLE>
<%
        try {
            StockQuotesSoap binding = new com.swanandmokashi.StockQuotesLocator().getStockQuotesSoap();
            ArrayOfQuote value = binding.getStockQuotes(request.getParameter("STOCK"));
            Quote[] q = value.getQuote();
            for(int i = 0; i < q.length; i++) {
%>
<TR>
<TD><%=q[i].getStockTicker()%></TD>
<TD><%=q[i].getOpenPrice()%></TD>
</TR>
<%
            }
        } catch (RemoteException ex) {
        } catch (ServiceException ex) {
        }
%>
</TABLE>
Avatar billede arne_v Ekspert
09. april 2003 - 08:58 #4
Genereret kode:

/**
* ArrayOfQuote.java
*
* This file was auto-generated from WSDL
* by the Apache Axis Wsdl2java emitter.
*/

package com.swanandmokashi;

public class ArrayOfQuote implements java.io.Serializable {
    private com.swanandmokashi.Quote[] quote;

    public ArrayOfQuote() {
    }

    public com.swanandmokashi.Quote[] getQuote() {
        return quote;
    }

    public void setQuote(com.swanandmokashi.Quote[] quote) {
        this.quote = quote;
    }

    public com.swanandmokashi.Quote getQuote(int i) {
        return quote[i];
    }

    public void setQuote(int i, com.swanandmokashi.Quote value) {
        if (this.quote == null ||
            this.quote.length <= i) {
            com.swanandmokashi.Quote[] a = new com.swanandmokashi.Quote[i + 1];
            if (this.quote != null) {
                for(int j = 0; j < this.quote.length; j++)
                    a[j] = this.quote[j];
            }
            this.quote = a;
        }
        this.quote[i] = value;
    }

    // Type metadata
    private static org.apache.axis.description.TypeDesc typeDesc =
        new org.apache.axis.description.TypeDesc();

    static {
        org.apache.axis.description.FieldDesc field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("quote");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "Quote"));
        typeDesc.addFieldDesc(field);
    };

    /**
    * Return type metadata object
    */
    public static org.apache.axis.description.TypeDesc getTypeDesc() {
        return typeDesc;
    }

    public boolean equals(Object obj) {
        // compare elements
        ArrayOfQuote other = (ArrayOfQuote) obj;
        if (obj == null) return false;
        if (this == obj) return true;
        if (! (obj instanceof ArrayOfQuote)) return false;
        return
            ((quote==null && other.getQuote()==null) ||
            (quote!=null &&
              quote.equals(other.getQuote())));
    }
}

/**
* Quote.java
*
* This file was auto-generated from WSDL
* by the Apache Axis Wsdl2java emitter.
*/

package com.swanandmokashi;

public class Quote implements java.io.Serializable {
    private java.lang.String companyName;
    private java.lang.String stockTicker;
    private java.lang.String stockQuote;
    private java.lang.String lastUpdated;
    private java.lang.String change;
    private java.lang.String openPrice;
    private java.lang.String dayHighPrice;  // attribute
    private java.lang.String dayLowPrice;  // attribute
    private java.lang.String volume;  // attribute
    private java.lang.String marketCap;  // attribute
    private java.lang.String yearRange;  // attribute

    public Quote() {
    }

    public java.lang.String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(java.lang.String companyName) {
        this.companyName = companyName;
    }

    public java.lang.String getStockTicker() {
        return stockTicker;
    }

    public void setStockTicker(java.lang.String stockTicker) {
        this.stockTicker = stockTicker;
    }

    public java.lang.String getStockQuote() {
        return stockQuote;
    }

    public void setStockQuote(java.lang.String stockQuote) {
        this.stockQuote = stockQuote;
    }

    public java.lang.String getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(java.lang.String lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    public java.lang.String getChange() {
        return change;
    }

    public void setChange(java.lang.String change) {
        this.change = change;
    }

    public java.lang.String getOpenPrice() {
        return openPrice;
    }

    public void setOpenPrice(java.lang.String openPrice) {
        this.openPrice = openPrice;
    }

    public java.lang.String getDayHighPrice() {
        return dayHighPrice;
    }

    public void setDayHighPrice(java.lang.String dayHighPrice) {
        this.dayHighPrice = dayHighPrice;
    }

    public java.lang.String getDayLowPrice() {
        return dayLowPrice;
    }

    public void setDayLowPrice(java.lang.String dayLowPrice) {
        this.dayLowPrice = dayLowPrice;
    }

    public java.lang.String getVolume() {
        return volume;
    }

    public void setVolume(java.lang.String volume) {
        this.volume = volume;
    }

    public java.lang.String getMarketCap() {
        return marketCap;
    }

    public void setMarketCap(java.lang.String marketCap) {
        this.marketCap = marketCap;
    }

    public java.lang.String getYearRange() {
        return yearRange;
    }

    public void setYearRange(java.lang.String yearRange) {
        this.yearRange = yearRange;
    }

    // Type metadata
    private static org.apache.axis.description.TypeDesc typeDesc =
        new org.apache.axis.description.TypeDesc();

    static {
        org.apache.axis.description.FieldDesc field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("dayHighPrice");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "DayHighPrice"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("marketCap");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "MarketCap"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("dayLowPrice");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "DayLowPrice"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("volume");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "Volume"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("lastUpdated");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "LastUpdated"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("openPrice");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "OpenPrice"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("change");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "Change"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("stockTicker");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "StockTicker"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("stockQuote");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "StockQuote"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("companyName");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "CompanyName"));
        typeDesc.addFieldDesc(field);
        field = new org.apache.axis.description.ElementDesc();
        field.setFieldName("yearRange");
        field.setXmlName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "YearRange"));
        typeDesc.addFieldDesc(field);
    };

    /**
    * Return type metadata object
    */
    public static org.apache.axis.description.TypeDesc getTypeDesc() {
        return typeDesc;
    }

    public boolean equals(Object obj) {
        // compare elements
        Quote other = (Quote) obj;
        if (obj == null) return false;
        if (this == obj) return true;
        if (! (obj instanceof Quote)) return false;
        return
            ((companyName==null && other.getCompanyName()==null) ||
            (companyName!=null &&
              companyName.equals(other.getCompanyName()))) &&
            ((stockTicker==null && other.getStockTicker()==null) ||
            (stockTicker!=null &&
              stockTicker.equals(other.getStockTicker()))) &&
            ((stockQuote==null && other.getStockQuote()==null) ||
            (stockQuote!=null &&
              stockQuote.equals(other.getStockQuote()))) &&
            ((lastUpdated==null && other.getLastUpdated()==null) ||
            (lastUpdated!=null &&
              lastUpdated.equals(other.getLastUpdated()))) &&
            ((change==null && other.getChange()==null) ||
            (change!=null &&
              change.equals(other.getChange()))) &&
            ((openPrice==null && other.getOpenPrice()==null) ||
            (openPrice!=null &&
              openPrice.equals(other.getOpenPrice()))) &&
            ((dayHighPrice==null && other.getDayHighPrice()==null) ||
            (dayHighPrice!=null &&
              dayHighPrice.equals(other.getDayHighPrice()))) &&
            ((dayLowPrice==null && other.getDayLowPrice()==null) ||
            (dayLowPrice!=null &&
              dayLowPrice.equals(other.getDayLowPrice()))) &&
            ((volume==null && other.getVolume()==null) ||
            (volume!=null &&
              volume.equals(other.getVolume()))) &&
            ((marketCap==null && other.getMarketCap()==null) ||
            (marketCap!=null &&
              marketCap.equals(other.getMarketCap()))) &&
            ((yearRange==null && other.getYearRange()==null) ||
            (yearRange!=null &&
              yearRange.equals(other.getYearRange())));
    }
}

/**
* StockQuotes.java
*
* This file was auto-generated from WSDL
* by the Apache Axis Wsdl2java emitter.
*/

package com.swanandmokashi;

public interface StockQuotes extends javax.xml.rpc.Service {
    public String getStockQuotesSoapAddress();

    public com.swanandmokashi.StockQuotesSoap getStockQuotesSoap() throws javax.xml.rpc.ServiceException;

    public com.swanandmokashi.StockQuotesSoap getStockQuotesSoap(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
}

/**
* StockQuotesLocator.java
*
* This file was auto-generated from WSDL
* by the Apache Axis Wsdl2java emitter.
*/

package com.swanandmokashi;

public class StockQuotesLocator extends org.apache.axis.client.Service implements com.swanandmokashi.StockQuotes {

    // Use to get a proxy class for StockQuotesSoap
    private final java.lang.String StockQuotesSoap_address = "http://www.swanandmokashi.com/HomePage/WebServices/StockQuotes.asmx";

    public String getStockQuotesSoapAddress() {
        return StockQuotesSoap_address;
    }

    public com.swanandmokashi.StockQuotesSoap getStockQuotesSoap() throws javax.xml.rpc.ServiceException {
      java.net.URL endpoint;
        try {
            endpoint = new java.net.URL(StockQuotesSoap_address);
        }
        catch (java.net.MalformedURLException e) {
            return null; // unlikely as URL was validated in WSDL2Java
        }
        return getStockQuotesSoap(endpoint);
    }

    public com.swanandmokashi.StockQuotesSoap getStockQuotesSoap(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
        try {
            com.swanandmokashi.StockQuotesSoapStub stub =  new com.swanandmokashi.StockQuotesSoapStub(portAddress, this);
            return stub;
        }
        catch (org.apache.axis.AxisFault e) {
            return null; // ???
        }
    }
}

/**
* StockQuotesSoap.java
*
* This file was auto-generated from WSDL
* by the Apache Axis Wsdl2java emitter.
*/

package com.swanandmokashi;

public interface StockQuotesSoap extends java.rmi.Remote {

    /**
    * Retrieves the latest(20 minutes delay) stock quote of a stock ticker.
    * To get multiple quotes enter Ticker symbols seperated by ,(eg. MSFT,YHOO,GE)
    * or space (eg. MSFT YHOO GE). <BR>Gives the company name ,ticker,Stock
    * Quote, Change,Open price ,Day's range(high and low),Volume, the Market
    * Cap and the Year range of the stock price.<BR><B>Powered by Yahoo!'s
    * stock Quotes service.Not for commerical use.For demo purposes only.</b>
    */
    public com.swanandmokashi.ArrayOfQuote getStockQuotes(java.lang.String quoteTicker) throws java.rmi.RemoteException;
}

/**
* StockQuotesSoapStub.java
*
* This file was auto-generated from WSDL
* by the Apache Axis Wsdl2java emitter.
*/

package com.swanandmokashi;

public class StockQuotesSoapStub extends org.apache.axis.client.Stub implements com.swanandmokashi.StockQuotesSoap {
    private java.util.Vector cachedSerClasses = new java.util.Vector();
    private java.util.Vector cachedSerQNames = new java.util.Vector();
    private java.util.Vector cachedSerFactories = new java.util.Vector();
    private java.util.Vector cachedDeserFactories = new java.util.Vector();

    public StockQuotesSoapStub() throws org.apache.axis.AxisFault {
        this(null);
    }

    public StockQuotesSoapStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
        this(service);
        super.cachedEndpoint = endpointURL;
    }

    public StockQuotesSoapStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
        try {
            if (service == null) {
                super.service = new org.apache.axis.client.Service();
            } else {
                super.service = service;
            }
            Class cls;
            javax.xml.rpc.namespace.QName qName;
            Class beansf = org.apache.axis.encoding.ser.BeanSerializerFactory.class;
            Class beandf = org.apache.axis.encoding.ser.BeanDeserializerFactory.class;
            Class enumsf = org.apache.axis.encoding.ser.EnumSerializerFactory.class;
            Class enumdf = org.apache.axis.encoding.ser.EnumDeserializerFactory.class;
            Class arraysf = org.apache.axis.encoding.ser.ArraySerializerFactory.class;
            Class arraydf = org.apache.axis.encoding.ser.ArrayDeserializerFactory.class;
            Class simplesf = org.apache.axis.encoding.ser.SimpleNonPrimitiveSerializerFactory.class;
            Class simpledf = org.apache.axis.encoding.ser.SimpleDeserializerFactory.class;
            qName = new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "Quote");
            cachedSerQNames.add(qName);
            cls = com.swanandmokashi.Quote.class;
            cachedSerClasses.add(cls);
            cachedSerFactories.add(beansf);
            cachedDeserFactories.add(beandf);

            qName = new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "ArrayOfQuote");
            cachedSerQNames.add(qName);
            cls = com.swanandmokashi.ArrayOfQuote.class;
            cachedSerClasses.add(cls);
            cachedSerFactories.add(beansf);
            cachedDeserFactories.add(beandf);

        }
        catch(Exception t) {
            throw org.apache.axis.AxisFault.makeFault(t);
        }
    }

    private org.apache.axis.client.Call getCall() throws java.rmi.RemoteException {
        try {
            org.apache.axis.client.Call call =
                    (org.apache.axis.client.Call) super.service.createCall();
            if (super.maintainSessionSet) {
                call.setMaintainSession(super.maintainSession);
            }
            if (super.cachedUsername != null) {
                call.setUsername(super.cachedUsername);
            }
            if (super.cachedPassword != null) {
                call.setPassword(super.cachedPassword);
            }
            if (super.cachedEndpoint != null) {
                call.setTargetEndpointAddress(super.cachedEndpoint);
            }
            if (super.cachedTimeout != null) {
                call.setTimeout(super.cachedTimeout);
            }
            java.util.Enumeration keys = super.cachedProperties.keys();
            while (keys.hasMoreElements()) {
                String key = (String) keys.nextElement();
                call.setProperty(key, super.cachedProperties.get(key));
            }
            // All the type mapping information is registered
            // when the first call is made.
            // The type mapping information is actually registered in
            // the TypeMappingRegistry of the service, which
            // is the reason why registration is only needed for the first call.
            if (firstCall()) {
                // must set encoding style before registering serializers
                call.setEncodingStyle(null);
                for (int i = 0; i < cachedSerFactories.size(); ++i) {
                    Class cls = (Class) cachedSerClasses.get(i);
                    javax.xml.rpc.namespace.QName qName =
                            (javax.xml.rpc.namespace.QName) cachedSerQNames.get(i);
                    Class sf = (Class)
                            cachedSerFactories.get(i);
                    Class df = (Class)
                            cachedDeserFactories.get(i);
                    call.registerTypeMapping(cls, qName, sf, df, false);
                }
            }
            return call;
        }
        catch (Throwable t) {
            throw new org.apache.axis.AxisFault("Failure trying to get the Call object", t);
        }
    }

    public com.swanandmokashi.ArrayOfQuote getStockQuotes(java.lang.String quoteTicker) throws java.rmi.RemoteException{
        if (super.cachedEndpoint == null) {
            throw new org.apache.axis.NoEndPointException();
        }
        org.apache.axis.client.Call call = getCall();
        javax.xml.rpc.namespace.QName p0QName = new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "QuoteTicker");
        call.addParameter(p0QName, new javax.xml.rpc.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), javax.xml.rpc.ParameterMode.PARAM_MODE_IN);
        call.setReturnType(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "ArrayOfQuote"));
        call.setUseSOAPAction(true);
        call.setSOAPActionURI("http://swanandmokashi.com/GetStockQuotes");
        call.setEncodingStyle(null);
        call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
        call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
        call.setOperationStyle("wrapped");
        call.setOperationName(new javax.xml.rpc.namespace.QName("http://swanandmokashi.com/", "GetStockQuotes"));

        Object resp = call.invoke(new Object[] {quoteTicker});

        if (resp instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException)resp;
        }
        else {
            return (com.swanandmokashi.ArrayOfQuote) resp;
        }
    }

}
Avatar billede arne_v Ekspert
09. april 2003 - 08:59 #5
Og så skal diverse Axis jar filer naturlivis deployes i
web app'ens lib directory.

Ihvertfald axis.jar, jaxrpc.jar og wsdl4j.jar - men muligvis flere
(tag dem alle sammen !).
Avatar billede speder Nybegynder
09. april 2003 - 09:04 #6
Ja, jeg tænkte nok at det ikke lige var til i ren jsp ;-)

Nu er problemet at jeg overhovedet ikke er ekspert i alt stykke sådan en pakke sammen. Kunne man forestille sig at du generere et war-fil med de nødvendige klasser og så jsp-test-siden. Og samtidig lige skrev et par linier om hvordan du genererer klassen med Apache Axis.

Så forhøjer jeg points til max.
Avatar billede arne_v Ekspert
09. april 2003 - 09:44 #7
Jeg kan godt lave en war-fil.

Men jeg må tilstå at jeg har snydt med den genererede kode i.s.f.
at kaldes Axis direkte har jeg brugt wizarden i JBuilder Enterprise Edition
(den bruger også Axis, men det er bare "New" "Import WSDL" og så fylder
man en text-box ud med URL og voila så har man det hele).
Avatar billede arne_v Ekspert
09. april 2003 - 11:03 #8
Jeg har nu en kørende web app.

Og jeg har set den returnere:

<HTML>
<HEAD>
<TITLE>Citrix</TITLE>
</HEAD>
<BODY>
<H1>Citrix</H1>
<TABLE>

<TR>
<TD>CTXS</TD>
<TD>14.28</TD>
</TR>

</TABLE>
</BODY>
</HTML>

jeg kan pakke en war med source og build script og smide den op for download
i aften.
Avatar billede arne_v Ekspert
09. april 2003 - 11:04 #9
Min test.jsp kom til at se ud som:
<%@ page import="java.rmi.*,javax.xml.rpc.*,com.swanandmokashi.*" %>
<HTML>
<HEAD>
<TITLE>Citrix</TITLE>
</HEAD>
<BODY>
<H1>Citrix</H1>
<TABLE>
<%
        try {
            StockQuotesSoap binding = new StockQuotesLocator().getStockQuotesSoap();
            ArrayOfQuote value = binding.getStockQuotes("CTXS");
            Quote[] q = value.getQuote();
            for(int i = 0; i < q.length; i++) {
%>
<TR>
<TD><%=q[i].getStockTicker()%></TD>
<TD><%=q[i].getOpenPrice()%></TD>
</TR>
<%
            }
        } catch (RemoteException ex) {
            ex.printStackTrace();
        } catch (ServiceException ex) {
            ex.printStackTrace();
        }
%>
</TABLE>
</BODY>
</HTML>
Avatar billede arne_v Ekspert
09. april 2003 - 11:05 #10
Og jeg måtte smide 5 mere jar-filer i lib log4j-core, commons-logging,
clutil, soap, tt-bytecode.
Avatar billede speder Nybegynder
09. april 2003 - 11:05 #11
det lyder godt - jeg tjekker lige efter i aften.
Avatar billede arne_v Ekspert
09. april 2003 - 18:43 #12
Avatar billede arne_v Ekspert
09. april 2003 - 19:15 #13
Ja det blev lige en ZIP-fil, fordi jeg har arbejdet med det udpakket.

(og du skal jo alligevel have rettet min test.jsp til så du skal alligevel
have udpakket)
Avatar billede arne_v Ekspert
09. april 2003 - 22:00 #14
Kan du få det til at virke hos dig ?
Avatar billede speder Nybegynder
10. april 2003 - 08:11 #15
hej - jeg fik desværre ikke tid til at se på det i aftes. prøver igen i aften.
Avatar billede speder Nybegynder
10. april 2003 - 19:59 #16
Nå, det endte med at jeg fandt et Axis plugin til Eclipse og lavede det på samme måde derigennem. Men jeg blev vist inspireret af dig, så du får points.

Ps. Har du nogle erfaringer med Eclipse vs. JBuilder?
Avatar billede arne_v Ekspert
10. april 2003 - 20:09 #17
Ja.

Jeg bruger begge.

Og er glad for begge.

Jeg foretrækker nok JBuilder Enterprise Edition til EJB, Web Services
og den slags.

Men til almindelige Java programmer er jeg meget glad for Eclipse - 95%
af mine stumper til Eksperten er lavet i Eclipse.

(det har var så lidt specielt)

Jeg har JB EE via mit arbejde - prisen er jo uhyrlig (på den forkerte
side af 30000 kr. hvis jeg husker rigtigt).
Avatar billede arne_v Ekspert
10. april 2003 - 20:19 #18
Jeps. Ravenholm har den til 27942 ekskl. moms.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester