Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
alx_java2b_20250412
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Patryk Czarnik
alx_java2b_20250412
Commits
1cc05d37
Commit
1cc05d37
authored
May 24, 2025
by
Patryk Czarnik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dodatkowa aplikacja PC29-RestTechnicznie
parent
2ccecbd3
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
570 additions
and
0 deletions
+570
-0
.gitignore
PC29-RestTechnicznie/.gitignore
+8
-0
pom.xml
PC29-RestTechnicznie/pom.xml
+45
-0
A.java
PC29-RestTechnicznie/src/main/java/rest/A.java
+13
-0
AplikacjaRestowa1.java
...RestTechnicznie/src/main/java/rest/AplikacjaRestowa1.java
+14
-0
AplikacjaRestowa2.java
...RestTechnicznie/src/main/java/rest/AplikacjaRestowa2.java
+31
-0
AplikacjaRestowa3.java
...RestTechnicznie/src/main/java/rest/AplikacjaRestowa3.java
+41
-0
B.java
PC29-RestTechnicznie/src/main/java/rest/B.java
+16
-0
C.java
PC29-RestTechnicznie/src/main/java/rest/C.java
+14
-0
EBean.java
PC29-RestTechnicznie/src/main/java/rest/EBean.java
+44
-0
Kalkulator.java
PC29-RestTechnicznie/src/main/java/rest/Kalkulator.java
+34
-0
Kontekst.java
PC29-RestTechnicznie/src/main/java/rest/Kontekst.java
+65
-0
Licznik.java
PC29-RestTechnicznie/src/main/java/rest/Licznik.java
+24
-0
Parametry.java
PC29-RestTechnicznie/src/main/java/rest/Parametry.java
+102
-0
Sesja.java
PC29-RestTechnicznie/src/main/java/rest/Sesja.java
+33
-0
ZwyklySerwlet.java
...-RestTechnicznie/src/main/java/serwlet/ZwyklySerwlet.java
+19
-0
index.html
PC29-RestTechnicznie/src/main/webapp/index.html
+67
-0
No files found.
PC29-RestTechnicznie/.gitignore
0 → 100644
View file @
1cc05d37
/target/
/.settings/
/.classpath
/.project
/*.iml
/.idea/
PC29-RestTechnicznie/pom.xml
0 → 100644
View file @
1cc05d37
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
pl.alx.kjava
</groupId>
<artifactId>
PC29-RestTechnicznie
</artifactId>
<version>
1.0
</version>
<packaging>
war
</packaging>
<name>
${project.artifactId}
</name>
<properties>
<maven.compiler.release>
17
</maven.compiler.release>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<failOnMissingWebXml>
false
</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>
jakarta.platform
</groupId>
<artifactId>
jakarta.jakartaee-web-api
</artifactId>
<version>
10.0.0
</version>
<scope>
provided
</scope>
</dependency>
</dependencies>
<build>
<finalName>
${project.artifactId}
</finalName>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.10.1
</version>
</plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-war-plugin
</artifactId>
<version>
3.3.2
</version>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
PC29-RestTechnicznie/src/main/java/rest/A.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
@Path
(
"/a"
)
public
class
A
{
@GET
public
String
get
()
{
return
"AAAAAAAA"
;
}
}
PC29-RestTechnicznie/src/main/java/rest/AplikacjaRestowa1.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
jakarta.ws.rs.ApplicationPath
;
import
jakarta.ws.rs.core.Application
;
// przykładowy adres
// http://localhost:8080/PC29-RestTechniczne/rest1/a
@ApplicationPath
(
"/rest1"
)
public
class
AplikacjaRestowa1
extends
Application
{
// Definicja aplikacji JAX-RS, w której skład wchodzą wszystkie dostępne w projekcie klasy oznaczone adnotacjami @Path lub @Provider
// Klasy zasobów działają w trybie "per-request" - dla każdego zapytania jest tworzony nowy obiekt klasy zasobu
// np. jest tworzony nowy wyzerowany licznik - /rest1/licznik będzie zawsze zwracać 1
}
PC29-RestTechnicznie/src/main/java/rest/AplikacjaRestowa2.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
java.util.HashSet
;
import
java.util.Set
;
import
jakarta.ws.rs.ApplicationPath
;
import
jakarta.ws.rs.core.Application
;
@ApplicationPath
(
"/rest2"
)
public
class
AplikacjaRestowa2
extends
Application
{
// Sam podaję klasy, które wchodzą w skład aplikacji JAX-RS
// Podaj się zarówno zasoby (@Path), jak i rozszerzenia (@Provider)
// Klasy zasobów działają w trybie "per-request"
// Czyli licznik /rest2/licznik będzie zawsze zwracać 1
@Override
public
Set
<
Class
<?>>
getClasses
()
{
// Są klasy A i B, a nie ma C
HashSet
<
Class
<?>>
zbior
=
new
HashSet
<>();
zbior
.
add
(
A
.
class
);
zbior
.
add
(
B
.
class
);
zbior
.
add
(
Licznik
.
class
);
zbior
.
add
(
Kontekst
.
class
);
zbior
.
add
(
EBean
.
class
);
return
zbior
;
// Od Javy 9:
// return Set.of(A.class, B.class, Licznik.class, Kontekst.class, EBean.class);
}
}
PC29-RestTechnicznie/src/main/java/rest/AplikacjaRestowa3.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
java.util.HashSet
;
import
java.util.Set
;
import
jakarta.ws.rs.ApplicationPath
;
import
jakarta.ws.rs.core.Application
;
@ApplicationPath
(
"/rest3"
)
public
class
AplikacjaRestowa3
extends
Application
{
// Sam podaję klasy, które wchodzą w skład aplikacji JAX-RS
// Podaj się zarówno zasoby (@Path), jak i rozszerzenia (@Provider)
@Override
public
Set
<
Class
<?>>
getClasses
()
{
System
.
out
.
println
(
"Aplikacja3.getClasses"
);
// te klasy działają w trybie "per-request"
HashSet
<
Class
<?>>
zbior
=
new
HashSet
<>();
zbior
.
add
(
A
.
class
);
zbior
.
add
(
Kontekst
.
class
);
return
zbior
;
}
// inne sposób, aby coś działało jako singleton: adotacja @Singleton przed klasą
@Override
public
Set
<
Object
>
getSingletons
()
{
System
.
out
.
println
(
"Aplikacja3.getSingletons"
);
Licznik
licznik
=
new
Licznik
();
licznik
.
setLicznik
(
100
);
// Te klasy działają w trybie singleton - ten sam obiekt obsługuje różne zapytania.
// Czyli licznik /rest3/licznik będzie zwraca coraz większe wartości
HashSet
<
Object
>
zbior
=
new
HashSet
<>();
zbior
.
add
(
new
B
());
zbior
.
add
(
new
Kontekst
());
zbior
.
add
(
licznik
);
zbior
.
add
(
new
EBean
());
return
zbior
;
}
}
PC29-RestTechnicznie/src/main/java/rest/B.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
@Path
(
"/b"
)
public
class
B
{
{
System
.
out
.
println
(
"Powstaje obiekt B"
);
}
@GET
public
String
get
()
{
return
"BBBB"
;
}
}
PC29-RestTechnicznie/src/main/java/rest/C.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
@Path
(
"/c"
)
public
class
C
{
@GET
public
String
get
()
{
return
"CCC"
;
}
}
PC29-RestTechnicznie/src/main/java/rest/EBean.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
java.io.Serializable
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
jakarta.annotation.PostConstruct
;
import
jakarta.annotation.PreDestroy
;
import
jakarta.ejb.Stateless
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
@Path
(
"/ejb"
)
@Stateless
// @Singleton // też działa
public
class
EBean
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
2627946805995054930L
;
private
AtomicInteger
licznik
=
new
AtomicInteger
();
// Dzięki temu, że jesteśmy w klasie EJB, można korzystać z adnotacji Java EE
// @PersistenceUnit
// private EntityManager em;
public
EBean
()
{
System
.
out
.
println
(
"EBean konstruktor"
);
}
@PostConstruct
public
void
postConstruct
()
{
System
.
out
.
println
(
"EBean @PostConstruct"
);
}
@PreDestroy
public
void
preDestroy
()
{
System
.
out
.
println
(
"EBean @PreDestroy"
);
}
@GET
public
String
get
()
{
return
"Hello EJB. Licznik = "
+
licznik
.
incrementAndGet
();
}
}
PC29-RestTechnicznie/src/main/java/rest/Kalkulator.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
import
jakarta.ws.rs.PathParam
;
@Path
(
"/calc"
)
public
class
Kalkulator
{
@GET
@Path
(
"/{x}+{y}"
)
public
long
dodaj
(
@PathParam
(
"x"
)
long
a
,
@PathParam
(
"y"
)
long
b
)
{
return
a
+
b
;
}
@GET
@Path
(
"/{x}-{y}"
)
public
long
odejmij
(
@PathParam
(
"x"
)
long
a
,
@PathParam
(
"y"
)
long
b
)
{
return
a
-
b
;
}
@GET
@Path
(
"/{x}*{y}"
)
public
long
pomnoz
(
@PathParam
(
"x"
)
long
a
,
@PathParam
(
"y"
)
long
b
)
{
return
a
*
b
;
}
@GET
@Path
(
"/{x}/{y}"
)
public
long
podziel
(
@PathParam
(
"x"
)
long
a
,
@PathParam
(
"y"
)
long
b
)
{
return
a
/
b
;
}
}
PC29-RestTechnicznie/src/main/java/rest/Kontekst.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
java.util.Arrays
;
import
java.util.Map
;
import
jakarta.servlet.ServletConfig
;
import
jakarta.servlet.ServletContext
;
import
jakarta.servlet.http.HttpServletRequest
;
import
jakarta.servlet.http.HttpServletResponse
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
import
jakarta.ws.rs.Produces
;
import
jakarta.ws.rs.core.Context
;
import
jakarta.ws.rs.core.HttpHeaders
;
import
jakarta.ws.rs.core.Request
;
import
jakarta.ws.rs.core.SecurityContext
;
import
jakarta.ws.rs.core.UriInfo
;
@Path
(
"/kontekst"
)
@Produces
(
"text/plain"
)
public
class
Kontekst
{
@GET
public
String
info
(
@Context
UriInfo
uriInfo
,
@Context
SecurityContext
securityContext
,
@Context
Request
restRequest
,
@Context
HttpHeaders
headers
,
@Context
ServletContext
servletContext
,
@Context
ServletConfig
servletConfig
,
@Context
HttpServletRequest
servletRequest
,
@Context
HttpServletResponse
servletResponse
)
{
StringBuilder
b
=
new
StringBuilder
();
b
.
append
(
"UriInfo\n"
);
b
.
append
(
"Base URI : "
).
append
(
uriInfo
.
getBaseUri
()).
append
(
'\n'
);
b
.
append
(
"Absolute path: "
).
append
(
uriInfo
.
getAbsolutePath
()).
append
(
'\n'
);
b
.
append
(
"Path : "
).
append
(
uriInfo
.
getPath
()).
append
(
'\n'
);
b
.
append
(
"\nHttpHeaders\n"
);
b
.
append
(
headers
.
getRequestHeaders
());
// Request restRequest - wiąże się z obsługą keszowania i typów zawartości
b
.
append
(
"\nServletContext\n"
);
b
.
append
(
"ServlerInfo: "
).
append
(
servletContext
.
getServerInfo
()).
append
(
'\n'
);
b
.
append
(
"\nServletRequest\n"
);
b
.
append
(
"RemoteAddr: "
).
append
(
servletRequest
.
getRemoteAddr
()).
append
(
'\n'
);
b
.
append
(
"LocalAddr : "
).
append
(
servletRequest
.
getLocalAddr
()).
append
(
'\n'
);
b
.
append
(
"URI : "
).
append
(
servletRequest
.
getRequestURI
()).
append
(
'\n'
);
b
.
append
(
"Parametry :\n"
);
for
(
Map
.
Entry
e
:
servletRequest
.
getParameterMap
().
entrySet
())
{
String
[]
v
=
(
String
[])
e
.
getValue
();
b
.
append
(
" * "
+
e
.
getKey
()
+
" : "
+
Arrays
.
toString
(
v
)
+
"\n"
);
}
b
.
append
(
"\nZalogowany wg serwletu: "
).
append
(
servletRequest
.
getRemoteUser
()).
append
(
'\n'
);
b
.
append
(
"Zalogowany wg SecurityContext: "
).
append
(
securityContext
.
getUserPrincipal
()).
append
(
'\n'
);
return
b
.
toString
();
}
}
PC29-RestTechnicznie/src/main/java/rest/Licznik.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
jakarta.ws.rs.Consumes
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.PUT
;
import
jakarta.ws.rs.Path
;
import
jakarta.ws.rs.Produces
;
@Path
(
"/licznik"
)
@Produces
(
"text/plain"
)
@Consumes
(
"text/plain"
)
public
class
Licznik
{
private
int
licznik
=
0
;
@GET
public
synchronized
int
getLicznik
()
{
return
++
licznik
;
}
@PUT
public
synchronized
void
setLicznik
(
int
licznik
)
{
this
.
licznik
=
licznik
;
}
}
PC29-RestTechnicznie/src/main/java/rest/Parametry.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
java.time.LocalDateTime
;
import
java.util.Arrays
;
import
jakarta.ws.rs.CookieParam
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.HeaderParam
;
import
jakarta.ws.rs.MatrixParam
;
import
jakarta.ws.rs.Path
;
import
jakarta.ws.rs.PathParam
;
import
jakarta.ws.rs.Produces
;
import
jakarta.ws.rs.QueryParam
;
import
jakarta.ws.rs.core.NewCookie
;
import
jakarta.ws.rs.core.Response
;
/* Przykładowe adresy z parametrami:
/rest1/parametry/query?a=Ala&b=Ola&b=Ela&t=Basia&t=Kasia&t=Zosia
/rest1/parametry/matrix;a=Ala;b=Ola;b=Ela;t=Basia;t=Kasia;t=Zosia
*/
@Path
(
"/parametry"
)
@Produces
(
"text/plain"
)
public
class
Parametry
{
@GET
@Path
(
"/query"
)
public
String
query
(
@QueryParam
(
"a"
)
String
a
,
@QueryParam
(
"b"
)
String
b
,
@QueryParam
(
"t"
)
String
[]
t
)
{
return
"Parametr a = "
+
a
+
"\nParametr b = "
+
b
+
"\nTablica: "
+
Arrays
.
toString
(
t
);
}
@GET
@Path
(
"/matrix"
)
public
String
matrix
(
@MatrixParam
(
"a"
)
String
a
,
@MatrixParam
(
"b"
)
String
b
,
@MatrixParam
(
"t"
)
String
[]
t
)
{
return
"Parametr a = "
+
a
+
"\nParametr b = "
+
b
+
"\nTablica: "
+
Arrays
.
toString
(
t
);
}
// /rest1/parametry/path/Ala/123/98765qwerty@res-zta
@GET
@Path
(
"/path/{a}/{b}/{cyfry:\\d+}{litery:\\w+}{reszta}"
)
public
String
pathParam
(
@PathParam
(
"a"
)
String
a
,
@PathParam
(
"b"
)
String
b
,
@PathParam
(
"cyfry"
)
String
cyfry
,
@PathParam
(
"litery"
)
String
litery
,
@PathParam
(
"reszta"
)
String
reszta
)
{
return
"Parametr a = "
+
a
+
"\nParametr b = "
+
b
+
"\nCyfry: "
+
cyfry
+
"\nLitery: "
+
litery
+
"\nReszta: "
+
reszta
;
}
@GET
@Path
(
"/headers"
)
public
String
headers
(
@HeaderParam
(
"accept"
)
String
accept
,
@HeaderParam
(
"user-agent"
)
String
agent
)
{
return
"Accept: "
+
accept
+
"\nUser-Agent: "
+
agent
;
}
@GET
@Path
(
"/cookies"
)
public
String
cookies
(
@CookieParam
(
"ciacho"
)
String
ciacho
,
@CookieParam
(
"JSESSIONID"
)
String
sessionId
)
{
return
"Ciacho: "
+
ciacho
+
"\nSesja: "
+
sessionId
;
}
@GET
@Path
(
"/ustaw"
)
// ustawia ciacho
public
Response
ustawCiacho
()
{
String
ciacho
=
LocalDateTime
.
now
().
toString
();
return
Response
.
ok
()
.
cookie
(
new
NewCookie
(
"ciacho"
,
ciacho
))
.
type
(
"text/plain"
)
.
entity
(
"Ustawiam ciacho na: "
+
ciacho
)
.
build
();
}
}
PC29-RestTechnicznie/src/main/java/rest/Sesja.java
0 → 100644
View file @
1cc05d37
package
rest
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
jakarta.servlet.http.HttpServletRequest
;
import
jakarta.servlet.http.HttpSession
;
import
jakarta.ws.rs.GET
;
import
jakarta.ws.rs.Path
;
import
jakarta.ws.rs.Produces
;
import
jakarta.ws.rs.core.Context
;
@Path
(
"/sesja"
)
public
class
Sesja
{
@Context
private
HttpServletRequest
request
;
@Produces
(
"text/plain"
)
@GET
public
int
licznik
()
{
HttpSession
sesja
=
request
.
getSession
();
AtomicInteger
licznik
=
null
;
synchronized
(
sesja
)
{
licznik
=
(
AtomicInteger
)
sesja
.
getAttribute
(
"x"
);
if
(
licznik
==
null
)
{
licznik
=
new
AtomicInteger
(
100
);
sesja
.
setAttribute
(
"x"
,
licznik
);
sesja
.
setMaxInactiveInterval
(
30
);
// po 30s sesja wygasa
}
}
return
licznik
.
getAndIncrement
();
// tak jakby return licznik++
}
}
PC29-RestTechnicznie/src/main/java/serwlet/ZwyklySerwlet.java
0 → 100644
View file @
1cc05d37
package
serwlet
;
import
java.io.IOException
;
import
jakarta.servlet.ServletException
;
import
jakarta.servlet.annotation.WebServlet
;
import
jakarta.servlet.http.HttpServlet
;
import
jakarta.servlet.http.HttpServletRequest
;
import
jakarta.servlet.http.HttpServletResponse
;
@WebServlet
(
"/serwlet"
)
public
class
ZwyklySerwlet
extends
HttpServlet
{
private
static
final
long
serialVersionUID
=
1L
;
protected
void
doGet
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException
,
IOException
{
response
.
getWriter
().
append
(
"Jestem zwyklym serwletem"
);
}
}
PC29-RestTechnicznie/src/main/webapp/index.html
0 → 100644
View file @
1cc05d37
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"UTF-8"
>
<title>
Elementy techniczne JAX-RS
</title>
</head>
<body>
<h1>
Elementy techniczne JAX-RS
</h1>
<ul>
<li><a
href=
"serwlet"
>
zwykły serwlet
</a>
- działający poza JAX-RS
</li>
</ul>
<h2>
Trzy wersje aplikacji
</h2>
<ol>
<li>
rest1 - ustawienia domyślne -
<i>
per request
</i>
<ul>
<li><a
href=
"rest1/a"
>
A
</a>
- istnieje
</li>
<li><a
href=
"rest1/b"
>
B
</a>
- istnieje
</li>
<li><a
href=
"rest1/c"
>
C
</a>
- istnieje
</li>
<li><a
href=
"rest1/licznik"
>
Licznik
</a>
- zawsze 1
</li>
</ul>
</li>
<li>
rest2 -
<code>
getClasses()
</code>
-
<i>
per request
</i>
<ul>
<li><a
href=
"rest2/a"
>
A
</a>
- istnieje
</li>
<li><a
href=
"rest2/b"
>
B
</a>
- istnieje
</li>
<li><a
href=
"rest2/c"
>
C
</a>
- nie istnieje
</li>
<li><a
href=
"rest2/licznik"
>
Licznik
</a>
- zawsze 1
</li>
</ul>
</li>
<li>
rest3 -
<code>
getSingletons()
</code>
- niektóre zasoby jako singletony
<ul>
<li><a
href=
"rest3/a"
>
A
</a>
- istnieje
</li>
<li><a
href=
"rest3/b"
>
B
</a>
- istnieje
</li>
<li><a
href=
"rest3/c"
>
C
</a>
- nie istnieje
</li>
<li><a
href=
"rest3/licznik"
>
Licznik
</a>
- globalny
</li>
</ul>
</li>
</ol>
<h2>
Elementy techniczne
</h2>
<ul>
<li><a
href=
"rest1/kontekst"
>
kontekst
</a>
- informacje wstrzyknięte za pomocą @Context
</li>
<li><a
href=
"rest1/sesja"
>
sesja
</a>
- licznik w sesji
</li>
<li><b>
Parametry
</b>
<ul>
<li><a
href=
"rest1/parametry/query?a=Ala&b=Ola&b=Ela&t=Basia&t=Kasia&t=Zosia"
>
@QueryParam
</a></li>
<li><a
href=
"rest1/parametry/matrix;a=Ala;b=Ola;b=Ela;t=Basia;t=Kasia;t=Zosia"
>
@MatrixParam
</a></li>
<li><a
href=
"rest1/parametry/path/Ala/123/98765qwerty@res-zta"
>
@PathParam
</a></li>
<li><a
href=
"rest1/parametry/headers"
>
@HeaderParam
</a></li>
<li><a
href=
"rest1/parametry/cookies"
>
@CookieParam
</a></li>
<li><a
href=
"rest1/parametry/ustaw"
>
Ustaw ciacho
</a></li>
</ul>
</li>
</ul>
<h2>
Kalkulator
</h2>
<ul>
<li><a
href=
"rest1/calc/12+13"
>
dodawanie
</a></li>
<li><a
href=
"rest1/calc/12*13"
>
mnożenie
</a></li>
</ul>
</body>
</html>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment