Merhabalar arkadaşlar. Bu yazıda JAX-RS içerisinde yer alan @Encoded notasyonunun kullanımını öğreneceğiz.

Önceki yazılarda birçok parametre alma çeşidi görmüştürk. URL’den gönderdiğimiz veriler web servis metodumuzdaki parametrelere enjekte ediliyordu. JAX-RS içerisinde olası veri kaybını önlemek ve daha sağlıklı iş yapmak için @Encoded notasyonu konularak olası riskler aşılmak istenmiş. @Encoded notasyonu nereye koyduğunuza bağlı olarak ilgili parametreyi encode ediyor ve web servis metoduna öyle veriyor. Varsayılan olarak bu encode edilmiş değer tekrar decode edilmiyor. Bizim decode işlemine tekrar tabi tutmamız gerekiyor. Şimdi önce @Encoded olmadan ne oluyor sonra da koyunca ne oluyor onu ve örnek uygulama ile nasıl kullanıldığını görelim.

EncodeAndEncoding.java

package rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

@Path("/encodedAndEncoding")
public class EncodedAndEncoding {
	@Path("/{pathParam}")
	@Produces(MediaType.TEXT_HTML)
	@GET	
	public String returnParameters(@PathParam("pathParam") String pathParam,
								   @QueryParam("queryParam") String queryParam){				
		return pathParam +" "+queryParam;
	}
}

Web servis sınıfımız daha önce gördüklerimizi içeren bir örnek. Bir adet PathParam ve bir adet QueryParam parametresi alıyor. Bu kodu çalıştırıp “Türkçe karakterler” muhteva eden /Hayvan Çiftliği?queryParam=Sırça Köşk şeklinde parametre gönderdiğimizde durum şöyle oluyor. Web servis metodunun Produce bilgisine charset=UTF-8 tanımlaması yapmadığımız için web servis metoduna parametreler sağlıklı da gitse tarayıcıda bozuk görünüyor.

Şimdi kod içindeki @PathParam ile alınan parametreyi @Encoded notasyonu ile de işaretleyelim ve ne oluyor bakalım.

@PathParam ile aldığımız Hayvan Çiftliği parametresi gördüğünüz gibi bir encoding işlemine maruz kaldı. Metotdaki ilgili parametreye encode edilmiş halde iken enjekte edildi ve biz de onu görüyoruz. Sırça köşk ise yine bozuk bir şekilde bize döndü. Peki böyle birden fazla parametre alan metotlarda her bir parametreyi @Encoded ile işaretleyecek miyiz? Hayır. @Encoded notasyonu metotlara da uygulanabilir. Şimdi @PathParam’ın yanındaki @Encoded’ı metotun üstüne alalım.

@Path("/encodedAndEncoding")
public class EncodedAndEncoding {
	@Path("/{pathParam}")
	@Produces(MediaType.TEXT_HTML)
	@GET
	@Encoded
	public String returnParameters(@PathParam("pathParam") String pathParam,
									@QueryParam("queryParam") String queryParam){				
		return pathParam +" "+queryParam;
	}
}

@Encoded’ı metodun üstüne aldığımızda metodun aldığı iki parametreye de encoding işlemi uygulanmış oldu. Bu sayede tek seferde tüm parametreleri encode edebiliriz. Tabi burda şu soru aklınıza gelebilir: “Bir sınıf içindeki tüm metotları tek tek @Encoding ile işaretlemek zorunda mıyız? Kısa yolu yok mu?”

@Encoding notasyonu sınıflara da uygulamabiliyor. Bu durumda sınıftaki tüm metotlar ve dolayısı ile aldıkları tüm parametreler encoding işlemine tabi tutulmuş olurlar. Kodu şöyle değiştirirsek amacımıza ulaşmış oluruz:

Path("/encodedAndEncoding")
@Encoded
public class EncodedAndEncoding {
	@Path("/{pathParam}")
	@Produces(MediaType.TEXT_HTML)
	@GET	
	public String returnParameters(@PathParam("pathParam") String pathParam,
									@QueryParam("queryParam") String queryParam){				
		return pathParam +" "+queryParam;
	}
}

Peki encode edilmiş veriden geri decode da etmemiz gerekiyor şu anda. Onu nasıl yapacağız? Hemen örneğe bakalım:

package rest;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import javax.ws.rs.Encoded;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/encodedAndEncoding")

public class EncodedAndEncoding {
	@Path("/{pathParam}")
	@Produces(MediaType.TEXT_HTML+";charset=UTF-8")
	@GET	
        @Encoded
	public String returnParameters(@PathParam("pathParam") String pathParam,
									@QueryParam("queryParam") String queryParam){
		System.out.println(pathParam +" "+queryParam);
		String decodedPathParam="";
		String decodedQueryParam="";
		try{
			decodedPathParam = URLDecoder.decode(pathParam,"UTF-8");
			System.out.println("Decoded Path Param:"+decodedPathParam);
			decodedQueryParam = URLDecoder.decode(queryParam,"UTF-8");
			System.out.println("Decoded Query Param"+decodedQueryParam);
			
		}
		catch(UnsupportedEncodingException exception){
			System.err.println("An error occured while trying the decoding!"+exception);
		}
		return pathParam + queryParam;
	}
}

Java’da encode edilmiş bir veriden decode işlemini java.net paketinde bulunan URLDecoder sınıfındaki decode metodu ile yapabiliriz. URLDecoder iki adet decode metoduna sahiptir. Sadece decode edilecek String’i alan metot artık deprecated olmuştur. Kullanımı geçerli olan metot ise hem String hem de decode edilecek charset’i alan metotdur. Ayrıca bu işlem bir Checked Exception’dır. Yani throws ya da try-catch ile hata meydana gelebileceğini söylememiz gerekir.

Konsol Çıktısı

Encode edilmiş parametrelerden decode işlemi ile asılları geri elde ettik.

Bu yazıda da bu kadar arkadaşlar. Gelecek yazıda görüşene kadar sağlıcakla kalın.

Selam ve Sevgilerimle