servlet etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
servlet etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

2 Mayıs 2015 Cumartesi

Servlet hakkında genel bilgiler

Servlet Nedir? Bir Servlet mimarisi nasil olmalidir?


Servlet ve Applet arasindaki farklar nelerdir?


GenericServlet ve HttpServlet arasindaki farklar nelerdir?


Servlet yasam dongusunden bahsedin?


doGet() ve doPost() arasindaki farklar nelerdir?


Web Application ne dir?


SSI, Server Side Include yapisini aciklayin?


Servlet Chaining nedir?


Client makinelerin servlet’lere istek gondermesinden bahsedin?


HTTP’nin yanit verme adimlarindan bahsedin?


Cookie nedir?


HTTP Tunneling nedir?


sendRedirect ve forward metodlari arasindaki farklar nelerdir?


URL Encoding ve URL Decoding yapilari nelerdir, aciklayiniz?


12 Mart 2015 Perşembe

Request Dispatcher nedir?

Bir servletten başka yere köprü kurarak, içinde obje de taşımak mümkün olan bir transfer çeşididir.

req.getRequestDispatcher(path) ;
req.setAttribute("...",entity);
dispatcher.forward(req,resp);
//entity buradaki req. parametresine yani requeste eklendi
//forward ile gönderildi.

şeklinde path adresine bir entity (yani nesne) transfer etmek mümkündür.

Bunun sebebi GET ya da POST kullanmadan yazmak istediğimiz içindir.

GET ile gönderilseydi GET abc?username=user&password=pass şeklinde de gönderilebilirdi.

Servlet vs. JSP vs. JSF

Servlet tasarımı kötü olduğundan ve basit bir işlem için çok fazla kod yazmak gerektiğinden kullanışlı değildir.
Servleti view olarak kullanmayız. Yani karmaşık olduğundan kullanıcıyla iletişime girmiyor.

Servlet ile JSP birbirine alternatif gibi görünse de aslında beraber çalışan teknolojilerdir.
MVC yani Model-View-Controller patternindeki view olarak JSP sayfaları, controller olarak da Servlet sınıfları kullanılıyor.





HTML form ve servlet

HTML form ve servlet

HTML formu tipik olarak şu şekildedir:

<form name="loginForm" method="post" action="loginServlet">
 Username: <input type="text" name="username"/> <br/>
 Password: <input type="password" name="password"/> <br/>
 <input type="submit" value="Login" />
</form>

Şimdi bu formu inceleyelim.

<form>

Form tagının attribute'leri şunlar:

- name : formun adı.
- method: form verisi gönderilirken kullanılacak olan HTTP metodu (GET ya da POST)
- action: servlet'in URL'si (başına '/' karakteri koymamaya dikkat etmek gerekiyor)
Yani servletin map'lendiği URL.
Örneğin web.xml'deki servlet mapping alanında şunlar belirtilmişse:
<servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.example.servlets.LoginServlet</servlet-class>
    </servlet>
<servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>
Bu servleti formda action kısmında action="loginServlet" olarak belirtmek gerekir.

Burada olan şey, login butonuna tıklandığı anda formun verilerini bir mesaja yükleyerek servletin url'sini çağırmaktır. Servlet gereken cevabı  /loginServlet URL adresinde bir html sayfası şeklinde gösterir.

Yani client /loginServlet adlı URL'yi istediğinde, servera önceden hazırlanıp konmuş olan sabit bir loginServlet.html sayfası döndürülmüyor.
Aksine, /loginServlet URL adresine maplenmiş olan, yani o adresin çağrılmasından sorumlu olan servlet dinamik olarak bir html sayfası yaratarak, belirtilen URL adresinde bu sayfayı browsera yazıyor.
İşte servletin dinamik olması buradan geliyor.

Login'e tıklandığında neler oluyor?

Form doldurulup "Login" butonuna tıklandığı anda browser servlet containera (Örneğin Tomcat server) bir HTTP POST isteği gönderir:
POST .../loginServlet HTTP/1.1
Host: xxx
Bu istek mesajının body kısmında da
username=asd&password=asd 
yazacaktır.

Servlet container (yani sunucu) bu mesajı alır. Aldığı anda service() metodu aracılığıyla gelen HTTP POST mesajını delege ederek LoginServlet instance yaratıp initialize eder(eğer henüz yaratılmamışsa). Ve bu instance'ın doPost() metodunu çalıştırır.
Servletin doPost() metodunda gelen istek bilgileri okunup cevaplanır.

<input>

Formun içinde input elemanları mevcut.
input tagı kullanıcının veri girişi yapabileceği alanları belirtir.
input tagının attribute'leri:

 -name: input alanının adı.

Servlet içerisinde istek parametrelerini almak için kullanılan HttpServletRequest nesnesinin getParameter(name) metodundaki name budur.
Input alanına sayı girilmesi gerekiyorsa, servlet içerisinde bunu int yada double olarak parse ederek kullanabiliriz.

- type: girilecek veri tipi.

"text" : yazı açık şekilde görülür.
"password" olursa yıldızlanarak gizlenir, ekranda şifrenin gizlenmesi sağlanır.
"checkbox" : tıklama kutusu.
"radio" : radyo butonu
"submit" olursa bir submit butonu oluşturulur. value ile verilen değer butonun üzerine yazılır.

Diğer input örnekleri

Checkbox

language:
<input type="checkbox" name="language" value="english" />English
<input type="checkbox" name="language" value="french" />French 

language: English French

String languages[] = request.getParameterValues("language");
if (languages != null) {
 System.out.println("Languages are: ");
 for (String lang : languages) {
  System.out.println("\t" + lang);
 }
} 

Languages are:
 english
 french

Radio button

Gender:
<input type="radio" name="gender" value="male" />Male
<input type="radio" name="gender" value="female" />Female 

Gender: Male Female

String gender = request.getParameter("gender");
System.out.println("Gender is: " + gender); 

Sonuç:
Gender is: male

Text area

Feedback:<br/>
<textarea rows="5" cols="30" name="feedback"></textarea> 

Feedback:


String feedback = request.getParameter("feedback");
System.out.println("Yorumunuz: " + feedback); 


Sonuç:
Yorumunuz: Hello!

Combobox / Dropdown

Job Category:
<select name="jobCat">
 <option value="tech">Technology</option>
 <option value="admin">Administration</option>
 <option value="biology">Biology</option>
 <option value="science">Science</option>
</select> 


Job Category:

String jobCategory = request.getParameter("jobCat");
System.out.println("Job category is: " + jobCategory); 
Sonuç:
Job category is: science 



...

JSP ve servlet ile yazılmış bir web application'ı manuel olarak deploy etme

1. Öncelikle environment'ta path değişkeninde JDK_HOME\bin bulunduğunu kontrol etmek gerekiyor. Bunu tanımlamadıkça komut satırından javac ve jar toollarına erişemiyoruz.

2. Servleti compile etmek için :

javac -cp TOMCAT_HOME\lib\servlet-api.jar" -d CLASS_DIR SRC_DIR\MyServlet.java

TOMCAT_HOME:  c:\Program Files\Apache Software Foundation\Tomcat 7.0. (path boşluk içeriyorsa çift tırnak içine alınmalı)
CLASS_DIR = WebContent\WEB-INF\classes
SRC_DIR = src\net\codejava\servlet

3. War dosyası oluşturmak için :

jar cfv deploy\MyWebApp.war -C WebContent .

4. Tomcata war ı deploy etmek için :

copy deploy\MyWebApp.war TOMCAT_HOME\webapps

5. Tomcati çalıştırmak için :

TOMCAT_HOME\bin\Tomcat7.exe

6. Browserdan url girerek web applicationı çalıştırmak için :

http://localhost:8080/MyWebApp

Default olarak index.jsp çalışır.

Servlet container nedir?

Servlet nedir? Nasıl kullanılır?

Servlet, client'tan gelen istekleri işleyip cevap gönderen bir server-side component'tir.
Tipik bir Java EE application'daki temel birimlerden biridir.
Diğerleri JSP, EJB, XML, vb'dir.
Servlet genelde JSP ile beraber client'tan gelen isteklere göre dinamik içerik yaratmakta kullanılır.
Servletler HttpServlet sınıfının doGet() ve doPost() metodlarını override ederek GET ve POST isteklerini yönetirler.

Örnek bir senaryoda:
1. JSP ile kullanıcının dolduracağı bir form gösterilir.
2. Form doldurulup gönder butonuna tıklandığında servlet çağırılır.
3. Servlet kullanıcının yazdığı veriyi işleyerek ona göre bir cevap gönderir.

Örneğin formun başında kullanıcının girdiği e-posta adresinin hatalı olduğunu belirten kırmızı bir uyarı yazısı belirebilir.
Ya da bazı alanların boş bırakılmaması gerektiği belirtilebilir.

Servlet container nedir?

Servlet container, java servletleri çalıştırabilen bir web server'dır.
Container sayesinde threadler, güvenlik, JSP processing, networking gibi konularla uğraşmamıza gerek kalmaz.
Container bizim için bunları kendisi hallettiğinden, biz sadece business logic üzerinde çalışabiliriz.

Not:Her web server, servlet container olamaz.
Örneğin Apache HTTP Server, sadece statik HTML sayfalarını sunabilir.
Fakat java servletleri çalıştıramaz. Bu yüzden de servlet container olamaz.
Tomcat ise hem HTTP listener, hem de JSP/servlet engine içerdiğinden hem statik, hem de dinamik HTML sayfalarını sunabilir. Bu yüzden servlet container olabilir.

En çok kullanılan servlet containerlar:
 - Apache Tomcat
 - Glassfish
 - JBoss
 - WebLogic

Servlet container istek ve cevapların kullanılabilmesi için servlete HttpServletRequest ve HttpServletResponse nesneleri verir.
Servlet bu nesneler aracılığıyla istekleri inceler ve cevapları hazırlar.

Servlet life cycle / yaşam döngüsü

Servlet container, yaşam döngüsü boyunca servletin şu metodlarını tetikler (invoke):

1. init()
Servletin yaşam döngüsünde (life cycle) bir kere çağırılır.
Client ilk kez servleti çağırdığında, servlet container bu metodu tetikler.
Burada genelde initialization kodları konulur.

2. doGet()
Client servlete HTTP GET isteğinde bulunduğu her seferde, bu metod tetiklenir.
Bu metoda servlet container iki nesne enjekte eder:

a. HttpServletRequest

Bu nesne istek parametreleri ve headerlarını wrap'ler.
Böylece servlet, getParameter() ve getHeader() metodlarını kullanarak client'ın yolladığı mesajın parametre ve headerlarına erişebilir.

b. HttpServletResponse

HTTP response headerlarını set etmek için ya da client'a HTML içeriği göndermek için kullanılır.

3. doPost()
Client servlete HTTP POST isteğinde bulunduğu her seferde bu metod tetiklenir.
Bu metodun aldığı iki parametre doGet() ile aynıdır.
Servlet, HttpServletRequest nesnesi ile client'tan gelen parametreleri alarak, işledikten sonra oluşan cevabı HttpServletResponse nesnesi ile client'a gönderir.

4. destroy()

Servlet container, web application durdurulacağı zaman ya da server kapanacağı zaman bu metodu tetikler.

9 Mart 2015 Pazartesi

Servlet nedir?


Java ile dinamik web sayfası yapmanın bir çok yolu vardır. Bunlardan birisi servlet'tir.
Servlet, clientten gelen isteğe göre cevap döndüren bir java classıdır.
Bu cevabı client'a önceden belirlenmiş formatta bir web sayfası olarak döndürür.

Kaynaklar:
Oracle JavaEE 6 tutorial : http://docs.oracle.com/javaee/6/tutorial/doc/bnafd.html
Tomcat 7 docs: https://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/annotation/WebServlet.html

Javadoc

Javadoc'taki bilgilere göre, javax.servlet interface'i bütün servletlerin implement etmesi gereken metodları içeriyor.

public interface Servlet 
Defines methods that all servlets must implement.
A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet or an HTTP servlet that extendsjavax.servlet.http.HttpServlet.
This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence:
  1. The servlet is constructed, then initialized with the init method.
  1. Any calls from clients to the service method are handled.
  1. The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.
In addition to the life-cycle methods, this interface provides the getServletConfig method, which the servlet can use to get any startup information, and the getServletInfo method, which allows the servlet to return basic information about itself, such as author, version, and copyright.

Bu interface'i implement eden GenericServlet sınıfı ( javax.servlet.GenericServlet ) genel amaçlı servlet sınıfıdır. Bu sınıftan kalıtım alarak örneğin bir ftp servlet de yazabiliriz.
public abstract class GenericServlet 
extends java.lang.Object
implements ServletServletConfig, java.io.Serializable

HttpServlet sınıfı işte bu GenericServlet'in alt sınıfıdır. HttpServlet ten kalıtım alındığında en azından bir metodu override etmek gerekir: genellikle doGet ya da doPost override edilir.
(Not: genellikle google seo konusundaki avantajı yüzünden doGet tercih ediliyor.)


public abstract class HttpServlet 
extends GenericServlet 
implements java.io.Serializable
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these:
  • doGet, if the servlet supports HTTP GET requests
  • doPost, for HTTP POST requests
  • doPut, for HTTP PUT requests
  • doDelete, for HTTP DELETE requests
  • init and destroy, to manage resources that are held for the life of the servlet
  • getServletInfo, which the servlet uses to provide information about itself
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).
Likewise, there's almost no reason to override the doOptions and doTrace methods.
Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections. See the Java Tutorial on Multithreaded Programming for more information on handling multiple threads in a Java program.

HTTP servlet nasıl çalışır?


1. Client servera request gönderir.
2. Server'da bu isteğe ait servlet belirlenir. Request bu servlete gönderilir.
3. Servlet bu gelen bilgileri alır ve oluşturulması gereken sonuçları üretir. Genellikle bu sonuçlar HTML sayfası şeklindedir.
4. Servlet oluşturduğu sonucu web servera gönderir.
5. Web server servletten aldığı sonucu requestin sahibi olan client'a gönderir.

HttpServlet class'ı

HTML isteklerini anlayarak, HTML response üretir. 
HttpServlet classını extend ederek kendi servlet'lerimizi yazabiliriz.
Bunun için önce Source Packages altına yeni bir package yaratarak içerisine servlet classlarını atarız.
Daha sonra JNDI için servletleri tanımlamamız gerekir.
Bunu yapmanın 2 yolu var:
1- web.xml ile, (Servlet 3.0 dan itibaren opsiyoneldir)
2-Annotation ile. (JSR-315 (Servlet 3.0) specification ile getirildi)
İki yöntemin de artıları ve eksileri var.
Not: Hem annotation, hem de web.xml de tanımlama yapılırsa annotation xml'i ezer.

-----------
JSR-315
- pdf dosyası: http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf
- JCP sayfası : https://jcp.org/en/jsr/detail?id=311
------------

1. web.xml ile servletleri tanımlamak

Bu yöntemin avantajı tek bir dosyada ekleme-çıkarma, değiştirme yapmanın kolay olmasıdır.
Ayrıca değişiklik yapıldığında serveri yeniden başlattığımız anda web.xml'in yeniden okunmasıyla değişiklikler geçerli olur.

Yapılacak işlemler:

 WEB-INF klasörü içerisine yeni bir web.xml dosyası yaratırız.

web.xml dosyası:
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>


Buraya servletleri tanımlarız.
Örneğin: IndexServlet.java adlı servlet'i tanımlarken, Servlets tabından add servlet element seçeneğini seçeriz.
Açılan add servlet penceresinde servlet adı, sınıfı, ve URL pattern belirtiriz (posts/* gibi).

web.xml dosyasında şu eklemeler yapılır:
<servlet>
        <servlet-name>IndexServ</servlet-name>
        <servlet-class>com.example.servlets.IndexServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>IndexServ</servlet-name>
        <url-pattern>/administrator</url-pattern>
    </servlet-mapping>

Böylece localhost:8080/administrator adresine bağlandığımızda servlet'ten gelen cevabı bir html sayfa olarak görürüz.

2. Annotation ile servlet tanımlamak

Javadoc : http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html

Servlet 3.0dan itibaren gelen bir yenilikle, servlet classının başına @WebServlet annotationı koyarak kolay bir şekilde tanımlama yapabiliriz.
web.xml dosyasına gitmeye gerek kalmadan, hızlı bir şekilde tanımlama işi halledilmiş olur.
Fakat burada yapılan bir değşikliğin etkisini göstermesi için bütün projenin yeniden compile edilmesi gerekir. Çünkü burada değişiklik class bazında olmaktadır.
Bu yüzden ufak bir değişiklikte bile bütün projeyi tekrardan compile etmek pek akıl karı değildir.

@WebServlet("/temppage")
public class TempServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter pw = resp.getWriter();
        pw.println("<html><head></head><body>");
        pw.println("<p> query: " + req.getQueryString() + "</p>");
        pw.println("</body></html>");
    }  
}
Bir servlet annotation'ı minimum şu şekilde olmalıdır:
@WebServlet("/notification")

Name, displayName, urlPatterns, vb diğer tanımlamaları da yazacaksak şu şekilde olmalıdır:
@WebServlet( name="NotificationServlet", displayName="Notification Servlet", urlPatterns = {"/notification"}, loadOnStartup=1)

service() metodu

Gelen isteğin tipine bakarak, kendi içeriğinde bulunan bu isteğe uygun metotları çalıştırır. Bu metodların adları “do” ile başlar: doGet ( ) , doDelete ( ) , vb.
Override edilmesi mümkündür fakat gereği yoktur.

init() metodu

Servlet ilk çalıştığında yapılacak genel işlemler için kullanılır.
Örneğin; veri tabanına bağlantı kurulması gerekiyorsa, bu işlemi bir kere init ( ) metodunda oluşturup gelen bütün isteklerde o bağlantıyı kullanabiliriz.
Yazdığımız servletin yaratılırken haber vermesini istiyorsak init() metodunu override ederiz.

Örnek bir Http Servlet

Projeye sağ tıklayıp Create new -> servlet diyerek yeni servlet yaratabiliriz.


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World!</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Hello World!</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

web.xml dosyası

Bir java servletin browserdan erişilebilmesi için önce servlet containera bunu bildirmek gerekiyor.

Servlet containera şunların bildirilmesi gerek:
1-hangi servletleri deploy edeceği
2-bu servletlerin hangi URLlere map edileceği
Web applicationın web.xml dosyasına bunları ilave ederek servlet containerı bilgilendirmiş oluyoruz.

Yani web.xml'deki servlet tanımının ilk bölümünde servlete bir isim verip class adını belirtiyoruz.
Buradan IndexServ adlı servletin aslında com.example.servlets paketinde bulunan IndexServlet sınıfında bulunduğunu anlıyoruz.
<servlet>
        <servlet-name>IndexServ</servlet-name>
        <servlet-class>com.example.servlets.IndexServlet</servlet-class>
    </servlet>

İkinci bölümde de servlete verilen isim bir URLe map ediliyor.
IndexServ adlı servletin sadece root'ta bulunan administrator sayfasında çalıştığını anlıyoruz.
    <servlet-mapping>
        <servlet-name>IndexServ</servlet-name>
        <url-pattern>/administrator</url-pattern>
    </servlet-mapping>


HttpServletRequest ve HttpServletResponse



HTTP servlet ile gelen requestin parametrelerini kontrol edebiliyoruz. Şöyle ki:
String username = req.getParameter("username");
yazdığımızda örneğin bir formdan gelen kullanıcı adı parametresini alıp username adlı local değişkene vermiş oluruz. Daha sonra parametrelerin doğruluğunu kontrol edip ona göre bir request hazırlayabiliriz.

Bunun dışında request mesajının headerlarını da inceleyebiliriz.
//bütün headerları alır
Enumeration<String> headers = req.getHeaders();
//host headerının değerini alır
String host = req.getHeader("host");
Servlet  requestte gelen parametre vb bilgileri alıp gerekli işlemleri yaptıktan sonra duruma göre bir cevap yani response hazırlar. İşte bunu doGet metodundaki HttpServletResponse parametresini kullanarak yapıyoruz.
//response parametresi bize bir PrintWriter sağlıyor
PrintWrite pw = resp.getWriter();
//bununla yazdığımız her şey browser ekranına sanki konsola yazarmışçasına basılıyor.
pw.println("<html><body><p>Hello</p></body></html>");


...

Servlet attribute'leri



value
or
urlPatterns
String[]
Required
Specify one or more URL patterns of the servlet. Either of attribute can be used, but not both.
name
String
Optional
Name of the servlet
displayName
String
Optional
Display name of the servlet
description
String
Optional
Description of the servlet
asyncSupported
boolean
Optional
Specify whether the servlet supports asynchronous operation mode. Default is false.
initParams
WebInitParam[]
Optional
Specify one or more initialization parameters of the servlet. Each parameter is specified by@WebInitParam annotation type.
loadOnStartup
int
Optional
Specify load-on-startup order of the servlet.
smallIcon
String
Optional
Specify name of the small icon of the servlet.
largeIcon
String
Optional
Specify name of the large icon of the servlet.


Servlet annotation tipleri



Annotation type
Equivalent XML elements in web.xml
None
<http-method-exception>
<http-method>
None
<security-constraint>
<filter>, <filter-mapping>
<init-param>
<listener>
<servlet>, <servlet-mapping>

Servlet annotation örnekleri


@WebServlet(urlPatterns = {"/sendFile""/uploadFile"})



@WebServlet(
        name = "MyOwnServlet",
        description = "This is my first annotated servlet",
        urlPatterns = "/processServlet"

)


@WebServlet(
        urlPatterns = "/imageUpload",
        initParams =
        {
            @WebInitParam(name = "saveDir", value = "D:/FileUpload"),
            @WebInitParam(name = "allowedTypes", value = "jpg,jpeg,gif,png")
        }
)


@WebServlet(

        urlPatterns = "/myController",

        loadOnStartup = 1,

        asyncSupported = true

)


Http Session UML diyagramı