{"id":32426,"date":"2025-10-21T15:41:30","date_gmt":"2025-10-21T12:41:30","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=32426"},"modified":"2025-10-21T15:41:30","modified_gmt":"2025-10-21T12:41:30","slug":"servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/","title":{"rendered":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler"},"content":{"rendered":"<p><body><\/p>\n<h2>Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler<\/h2>\n<h2>Giri\u015f: Web Uygulamalar\u0131nda Dosya Y\u00fcklemenin \u00d6nemi<\/h2>\n<p>Modern web uygulamalar\u0131n\u0131n vazge\u00e7ilmez \u00f6zelliklerinden biri, kullan\u0131c\u0131lar\u0131n sunucuya dosya y\u00fckleyebilmesidir. Profil resimleri, belgeler, videolar veya di\u011fer medya t\u00fcrleri olsun, dosya y\u00fckleme yetene\u011fi kullan\u0131c\u0131 etkile\u015fimini zenginle\u015ftirir ve uygulamalar\u0131n i\u015flevselli\u011fini art\u0131r\u0131r. Ancak, bu basit g\u00f6r\u00fcnen i\u015flem, arka planda karma\u015f\u0131k teknik zorluklar\u0131 bar\u0131nd\u0131r\u0131r. Dosya y\u00fckleme i\u015flemi, a\u011f \u00fczerinden b\u00fcy\u00fck veri bloklar\u0131n\u0131n g\u00fcvenli ve verimli bir \u015fekilde aktar\u0131lmas\u0131n\u0131, sunucu taraf\u0131nda do\u011fru \u015fekilde ayr\u0131\u015ft\u0131r\u0131lmas\u0131n\u0131, depolanmas\u0131n\u0131 ve potansiyel g\u00fcvenlik risklerine kar\u015f\u0131 korunmas\u0131n\u0131 gerektirir.<\/p>\n<p>Geleneksel olarak, Servlet API&#8217;sinin ilk s\u00fcr\u00fcmlerinde (2.x ve \u00f6ncesi) dosya y\u00fckleme i\u015flemleri olduk\u00e7a zahmetliydi. Geli\u015ftiricilerin, HTTP iste\u011finin g\u00f6vdesini (request body) manuel olarak okumas\u0131, <code>multipart\/form-data<\/code> format\u0131n\u0131 ayr\u0131\u015ft\u0131rmas\u0131 ve y\u00fcklenen dosyalar\u0131 bellek veya disk \u00fczerinde y\u00f6netmesi gerekiyordu. Bu s\u00fcre\u00e7, genellikle \u00fc\u00e7\u00fcnc\u00fc taraf k\u00fct\u00fcphanelerin (\u00f6rne\u011fin, Apache Commons FileUpload) kullan\u0131lmas\u0131n\u0131 zorunlu k\u0131l\u0131yordu. Bu k\u00fct\u00fcphaneler, dosya y\u00fckleme s\u00fcrecini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde basitle\u015ftirse de, geli\u015ftiricilerin yine de ek ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00f6netmesi ve k\u00fct\u00fcphanelerin API&#8217;sini \u00f6\u011frenmesi gerekiyordu. Servlet 3.0 ile birlikte, Java EE 6 platformunun bir par\u00e7as\u0131 olarak, dosya y\u00fckleme i\u015flemleri i\u00e7in standartla\u015ft\u0131r\u0131lm\u0131\u015f ve yerel bir API sunuldu. Bu yenilik, geli\u015ftiricilerin \u00fc\u00e7\u00fcnc\u00fc taraf k\u00fct\u00fcphanelere olan ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n\u0131 azaltarak, dosya y\u00fckleme s\u00fcre\u00e7lerini daha kolay, daha g\u00fcvenli ve daha verimli hale getirdi. Bu makale, Servlet 3.0&#8217;\u0131n getirdi\u011fi <code>@MultipartConfig<\/code> anotasyonu ve <code>Part<\/code> aray\u00fcz\u00fcn\u00fc kullanarak dosya y\u00fckleme i\u015flemlerinin nas\u0131l ger\u00e7ekle\u015ftirildi\u011fini detayl\u0131 bir \u015fekilde inceleyecektir.<\/p>\n<h2>Servlet 3.0 \u00d6ncesi Dosya Y\u00fckleme Zorluklar\u0131<\/h2>\n<p>Servlet 3.0 \u00f6ncesinde, web taray\u0131c\u0131lar\u0131 ve sunucular aras\u0131nda dosya y\u00fcklemek i\u00e7in <code>multipart\/form-data<\/code> MIME t\u00fcr\u00fc kullan\u0131l\u0131rd\u0131. Bu format, bir HTTP POST iste\u011fi i\u00e7inde birden fazla veri par\u00e7as\u0131n\u0131 (form alanlar\u0131 ve dosyalar) tek bir istekte g\u00f6ndermeyi m\u00fcmk\u00fcn k\u0131lar. Ancak, Servlet 2.x API&#8217;si bu format\u0131 do\u011frudan ayr\u0131\u015ft\u0131rma yetene\u011fine sahip de\u011fildi.<\/p>\n<p>Bir Servlet&#8217;e gelen <code>HttpServletRequest<\/code> nesnesi, <code>multipart\/form-data<\/code> ile g\u00f6nderilen verileri standart <code>getParameter()<\/code> metoduyla do\u011frudan okuyamazd\u0131. Bunun yerine, geli\u015ftiricilerin <code>request.getInputStream()<\/code> metodunu kullanarak HTTP iste\u011finin ham baytlar\u0131n\u0131 okumas\u0131 ve bu bayt ak\u0131\u015f\u0131n\u0131 <code>multipart\/form-data<\/code> format\u0131n\u0131n kurallar\u0131na g\u00f6re manuel olarak ayr\u0131\u015ft\u0131rmas\u0131 gerekiyordu. Bu i\u015flem, her bir veri par\u00e7as\u0131n\u0131n (b\u00f6l\u00fcm\u00fcn) s\u0131n\u0131rlar\u0131n\u0131 belirleyen &#8220;boundary&#8221; dizgisini aramak, her b\u00f6l\u00fcm\u00fcn ba\u015fl\u0131klar\u0131n\u0131 (header) okumak (\u00f6rne\u011fin, <code>Content-Disposition<\/code>, <code>Content-Type<\/code>) ve dosya i\u00e7eri\u011fini ay\u0131klamak gibi karma\u015f\u0131k ad\u0131mlar\u0131 i\u00e7eriyordu.<\/p>\n<p>Bu manuel ayr\u0131\u015ft\u0131rma s\u00fcreci:<br \/>\n*   <strong>Hataya a\u00e7\u0131kt\u0131:<\/strong> Yanl\u0131\u015f ayr\u0131\u015ft\u0131rma, veri kayb\u0131na veya g\u00fcvenlik a\u00e7\u0131klar\u0131na yol a\u00e7abilirdi.<br \/>\n*   <strong>Zaman al\u0131c\u0131yd\u0131:<\/strong> Geli\u015ftiricilerin, dosya y\u00fckleme mant\u0131\u011f\u0131n\u0131 her seferinde s\u0131f\u0131rdan yazmas\u0131 veya kopyala-yap\u0131\u015ft\u0131r yapmas\u0131 gerekiyordu.<br \/>\n*   <strong>Verimsizdi:<\/strong> B\u00fcy\u00fck dosyalarla \u00e7al\u0131\u015f\u0131rken bellek y\u00f6netimi ve disk I\/O i\u015flemleri optimize edilmemi\u015f olabilirdi.<\/p>\n<p>Bu zorluklar\u0131 a\u015fmak i\u00e7in Apache Commons FileUpload gibi k\u00fct\u00fcphaneler ortaya \u00e7\u0131kt\u0131. Bu k\u00fct\u00fcphaneler, <code>multipart\/form-data<\/code> ayr\u0131\u015ft\u0131rma i\u015flemini soyutlayarak geli\u015ftiricilere daha basit bir API sundu. Ancak, bu yakla\u015f\u0131m da projeye harici bir ba\u011f\u0131ml\u0131l\u0131k eklemek, k\u00fct\u00fcphanenin API&#8217;sini \u00f6\u011frenmek ve potansiyel s\u00fcr\u00fcm \u00e7ak\u0131\u015fmalar\u0131 gibi ek y\u00f6netim y\u00fckleri getiriyordu. Servlet 3.0, bu zorluklara standart ve yerle\u015fik bir \u00e7\u00f6z\u00fcm sunarak geli\u015ftiricilerin hayat\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde kolayla\u015ft\u0131rd\u0131.<\/p>\n<h2>Servlet 3.0 ile Gelen Yenilikler: @MultipartConfig ve Part Aray\u00fcz\u00fc<\/h2>\n<p>Java EE 6 platformunun bir par\u00e7as\u0131 olarak tan\u0131t\u0131lan Servlet 3.0 (JSR 315), web uygulamalar\u0131nda dosya y\u00fckleme deneyimini temelden de\u011fi\u015ftirdi. Bu s\u00fcr\u00fcmle birlikte, dosya y\u00fckleme i\u015flemleri i\u00e7in standartla\u015ft\u0131r\u0131lm\u0131\u015f iki ana bile\u015fen sunuldu: <code>@MultipartConfig<\/code> anotasyonu ve <code>Part<\/code> aray\u00fcz\u00fc.<\/p>\n<h3>@MultipartConfig Anotasyonu<\/h3>\n<p><code>@MultipartConfig<\/code> anotasyonu, bir Servlet&#8217;in <code>multipart\/form-data<\/code> isteklerini i\u015fleyebilece\u011fini belirtir ve dosya y\u00fckleme davran\u0131\u015f\u0131n\u0131 yap\u0131land\u0131rmak i\u00e7in kullan\u0131l\u0131r. Bu anotasyon, do\u011frudan Servlet s\u0131n\u0131f\u0131n\u0131n \u00fczerine veya <code>web.xml<\/code> da\u011f\u0131t\u0131m tan\u0131mlay\u0131c\u0131s\u0131ndaki <code><servlet><\/code> etiketi i\u00e7inde <code><multipart-config><\/code> alt etiketiyle kullan\u0131labilir.<\/p>\n<p><strong>Kullan\u0131m Amac\u0131:<\/strong><br \/>\n*   Servlet kapsay\u0131c\u0131s\u0131na (\u00f6rne\u011fin, Tomcat, Jetty) bu Servlet&#8217;in <code>multipart\/form-data<\/code> t\u00fcr\u00fcndeki istekleri otomatik olarak ayr\u0131\u015ft\u0131rmas\u0131 gerekti\u011fini bildirir.<br \/>\n*   Y\u00fcklenen dosyalar\u0131n ge\u00e7ici olarak nerede depolanaca\u011f\u0131n\u0131, maksimum dosya boyutlar\u0131n\u0131 ve bellekte tutulacak dosya boyut e\u015fiklerini belirler.<\/p>\n<p><strong>Temel Parametreler:<\/strong><br \/>\n*   <code>location<\/code>: Y\u00fcklenen dosyalar\u0131n ge\u00e7ici olarak depolanaca\u011f\u0131 dizin yolunu belirtir. Bu dizin yoksa Servlet kapsay\u0131c\u0131s\u0131 taraf\u0131ndan olu\u015fturulur. E\u011fer belirtilmezse, kapsay\u0131c\u0131n\u0131n varsay\u0131lan ge\u00e7ici dizini kullan\u0131l\u0131r. \u00d6rne\u011fin: <code>location = \"\/tmp\/uploads\"<\/code><br \/>\n*   <code>maxFileSize<\/code>: Tek bir y\u00fcklenen dosyan\u0131n izin verilen maksimum boyutunu bayt cinsinden belirtir. Bu e\u015fi\u011fi a\u015fan bir dosya y\u00fcklendi\u011finde <code>IllegalStateException<\/code> f\u0131rlat\u0131l\u0131r. Varsay\u0131lan de\u011fer -1&#8217;dir (s\u0131n\u0131rs\u0131z). \u00d6rne\u011fin: <code>maxFileSize = 1048576<\/code> (1 MB)<br \/>\n*   <code>maxRequestSize<\/code>: T\u00fcm <code>multipart\/form-data<\/code> iste\u011finin (t\u00fcm dosyalar ve form alanlar\u0131 dahil) izin verilen maksimum boyutunu bayt cinsinden belirtir. Bu e\u015fi\u011fi a\u015fan bir istekte yine <code>IllegalStateException<\/code> f\u0131rlat\u0131l\u0131r. Varsay\u0131lan de\u011fer -1&#8217;dir (s\u0131n\u0131rs\u0131z). \u00d6rne\u011fin: <code>maxRequestSize = 5242880<\/code> (5 MB)<br \/>\n*   <code>fileSizeThreshold<\/code>: Dosyalar\u0131n diske yaz\u0131lmadan \u00f6nce bellekte tutulaca\u011f\u0131 bayt cinsinden e\u015fi\u011fi belirtir. Bu e\u015fikten daha k\u00fc\u00e7\u00fck dosyalar bellekte tutulur, daha b\u00fcy\u00fck dosyalar ise <code>location<\/code> parametresiyle belirtilen ge\u00e7ici dizine diske yaz\u0131l\u0131r. Bu, k\u00fc\u00e7\u00fck dosyalar i\u00e7in disk I\/O&#8217;dan ka\u00e7\u0131narak performans\u0131 art\u0131rabilir. Varsay\u0131lan de\u011fer 0&#8217;d\u0131r. \u00d6rne\u011fin: <code>fileSizeThreshold = 2048<\/code> (2 KB)<\/p>\n<p><strong>\u00d6rnek Kullan\u0131m:<\/strong><\/p>\n<pre><code class=\"language-java\">import javax.servlet.annotation.MultipartConfig;\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\n\/\/ ... di\u011fer importlar\n\n@WebServlet(\"\/uploadServlet\")\n@MultipartConfig(\n    fileSizeThreshold = 1024 <em> 1024 <\/em> 2, \/\/ 2MB\n    maxFileSize = 1024 <em> 1024 <\/em> 10,      \/\/ 10MB\n    maxRequestSize = 1024 <em> 1024 <\/em> 50,   \/\/ 50MB\n    location = \"\/opt\/temp\/upload\"        \/\/ Ge\u00e7ici dosya depolama yolu\n)\npublic class FileUploadServlet extends HttpServlet {\n    \/\/ ... doPost metodu burada olacak\n}<\/code><\/pre>\n<h3>Part Aray\u00fcz\u00fc<\/h3>\n<p><code>@MultipartConfig<\/code> ile bir Servlet&#8217;in <code>multipart\/form-data<\/code> isteklerini i\u015fleyebilece\u011fi belirtildikten sonra, Servlet kapsay\u0131c\u0131s\u0131 gelen iste\u011fi otomatik olarak ayr\u0131\u015ft\u0131r\u0131r ve her bir b\u00f6l\u00fcm\u00fc (form alan\u0131 veya dosya) bir <code>javax.servlet.http.Part<\/code> nesnesi olarak temsil eder. <code>Part<\/code> aray\u00fcz\u00fc, y\u00fcklenen dosyalara ve form alanlar\u0131na eri\u015fmek i\u00e7in standart bir API sa\u011flar.<\/p>\n<p><strong>Part Nesnesi Elde Etme:<\/strong><br \/>\n<code>HttpServletRequest<\/code> nesnesi \u00fczerinde iki yeni metod bulunur:<br \/>\n*   <code>getPart(String name)<\/code>: Belirtilen <code>name<\/code> (form alan\u0131n\u0131n <code>name<\/code> \u00f6zniteli\u011fi) ile e\u015fle\u015fen <code>Part<\/code> nesnesini d\u00f6nd\u00fcr\u00fcr. E\u011fer birden fazla ayn\u0131 <code>name<\/code>&#8216;e sahip b\u00f6l\u00fcm varsa, ilkini d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <code>getParts()<\/code>: \u0130stekteki t\u00fcm <code>Part<\/code> nesnelerinin bir <code>Collection<Part><\/code>&#8216;\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr.<\/p>\n<p><strong>Temel Metotlar:<\/strong><br \/>\n*   <code>String getName()<\/code>: Bu b\u00f6l\u00fcm\u00fcn (form alan\u0131 veya dosya) ad\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr. Bu, HTML formundaki <code>input<\/code> etiketinin <code>name<\/code> \u00f6zniteli\u011fine kar\u015f\u0131l\u0131k gelir.<br \/>\n*   <code>String getSubmittedFileName()<\/code>: E\u011fer bu b\u00f6l\u00fcm bir dosya ise, istemci taraf\u0131ndan g\u00f6nderilen dosya ad\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr. G\u00fcvenlik nedeniyle bu ad\u0131n do\u011frudan kullan\u0131lmas\u0131 \u00f6nerilmez.<br \/>\n*   <code>long getSize()<\/code>: Bu b\u00f6l\u00fcm\u00fcn bayt cinsinden boyutunu d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <code>String getContentType()<\/code>: E\u011fer bu b\u00f6l\u00fcm bir dosya ise, dosyan\u0131n MIME t\u00fcr\u00fcn\u00fc (\u00f6rne\u011fin, <code>image\/jpeg<\/code>, <code>application\/pdf<\/code>) d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <code>InputStream getInputStream()<\/code>: Bu b\u00f6l\u00fcm\u00fcn i\u00e7eri\u011fini okumak i\u00e7in bir <code>InputStream<\/code> d\u00f6nd\u00fcr\u00fcr. Bu, dosyay\u0131 manuel olarak i\u015flemek veya kaydetmek i\u00e7in kullan\u0131l\u0131r.<br \/>\n*   <code>void write(String fileName)<\/code>: Bu b\u00f6l\u00fcm\u00fcn i\u00e7eri\u011fini belirtilen dosya ad\u0131na kaydeder. Dosya, <code>location<\/code> parametresiyle belirtilen dizine veya varsay\u0131lan ge\u00e7ici dizine kaydedilir.<br \/>\n*   <code>void delete()<\/code>: Bu b\u00f6l\u00fcmle ili\u015fkili ge\u00e7ici depolama kaynaklar\u0131n\u0131 (varsa) siler. \u0130stek tamamland\u0131\u011f\u0131nda Servlet kapsay\u0131c\u0131s\u0131 bu temizli\u011fi otomatik olarak yapar, ancak manuel olarak da \u00e7a\u011fr\u0131labilir.<br \/>\n*   <code>String getHeader(String name)<\/code>: Belirtilen ba\u015fl\u0131\u011f\u0131n de\u011ferini d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <code>Collection<String> getHeaders(String name)<\/code>: Belirtilen ba\u015fl\u0131\u011f\u0131n t\u00fcm de\u011ferlerini d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <code>Collection<String> getHeaderNames()<\/code>: T\u00fcm ba\u015fl\u0131k adlar\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr.<\/p>\n<p><code>@MultipartConfig<\/code> ve <code>Part<\/code> aray\u00fczleri, dosya y\u00fckleme i\u015flemlerini standartla\u015ft\u0131rarak ve karma\u015f\u0131k ayr\u0131\u015ft\u0131rma mant\u0131\u011f\u0131n\u0131 Servlet kapsay\u0131c\u0131s\u0131na devrederek geli\u015ftiricilerin i\u015fini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde kolayla\u015ft\u0131rm\u0131\u015ft\u0131r. Art\u0131k geli\u015ftiriciler, dosya y\u00fckleme mant\u0131\u011f\u0131na odaklanabilir ve d\u00fc\u015f\u00fck seviyeli detaylarla u\u011fra\u015fmak zorunda kalmazlar.<\/p>\n<h2>@MultipartConfig Anotasyonu Detayl\u0131 \u0130nceleme<\/h2>\n<p><code>@MultipartConfig<\/code> anotasyonu, Servlet 3.0 ile gelen dosya y\u00fckleme API&#8217;sinin temel yap\u0131 ta\u015flar\u0131ndan biridir. Bu anotasyonun do\u011fru \u015fekilde yap\u0131land\u0131r\u0131lmas\u0131, dosya y\u00fckleme i\u015flemlerinin hem verimli hem de g\u00fcvenli bir \u015fekilde ger\u00e7ekle\u015fmesini sa\u011flar.<\/p>\n<h3>Kullan\u0131m Alan\u0131 ve Amac\u0131<\/h3>\n<p><code>@MultipartConfig<\/code> anotasyonu, genellikle bir <code>HttpServlet<\/code> s\u0131n\u0131f\u0131n\u0131n \u00fczerine <code>@WebServlet<\/code> anotasyonu ile birlikte yerle\u015ftirilir. Bu, belirli bir URL deseniyle e\u015fle\u015fen istekleri i\u015fleyecek olan Servlet&#8217;in <code>multipart\/form-data<\/code> tipindeki i\u00e7erikleri otomatik olarak ayr\u0131\u015ft\u0131rmas\u0131 gerekti\u011fini Servlet kapsay\u0131c\u0131s\u0131na bildirir. Alternatif olarak, <code>web.xml<\/code> da\u011f\u0131t\u0131m tan\u0131mlay\u0131c\u0131s\u0131nda <code><servlet><\/code> etiketi alt\u0131nda <code><multipart-config><\/code> alt etiketi kullan\u0131larak da yap\u0131land\u0131r\u0131labilir. Bu y\u00f6ntem, \u00f6zellikle anotasyonlar\u0131n kullan\u0131lamad\u0131\u011f\u0131 durumlarda veya merkezi bir yap\u0131land\u0131rma gerekti\u011finde tercih edilebilir.<\/p>\n<p><strong>\u00d6rnek <code>web.xml<\/code> Yap\u0131land\u0131rmas\u0131:<\/strong><\/p>\n<pre><code class=\"language-xml\"><servlet>\n    <servlet-name>FileUploadServlet<\/servlet-name>\n    <servlet-class>com.example.FileUploadServlet<\/servlet-class>\n    <multipart-config>\n        <location>\/opt\/temp\/upload<\/location>\n        <max-file-size>10485760<\/max-file-size> <!-- 10MB -->\n        <max-request-size>52428800<\/max-request-size> <!-- 50MB -->\n        <file-size-threshold>2097152<\/file-size-threshold> <!-- 2MB -->\n    <\/multipart-config>\n<\/servlet>\n<servlet-mapping>\n    <servlet-name>FileUploadServlet<\/servlet-name>\n    <url-pattern>\/uploadServlet<\/url-pattern>\n<\/servlet-mapping><\/code><\/pre>\n<h3>Parametreler<\/h3>\n<p>Anotasyonun her bir parametresi, dosya y\u00fckleme s\u00fcrecinin farkl\u0131 bir y\u00f6n\u00fcn\u00fc kontrol eder ve dikkatli bir \u015fekilde ayarlanmal\u0131d\u0131r.<\/p>\n<p>*   <strong><code>location<\/code><\/strong>:<br \/>\n    *   <strong>Ama\u00e7:<\/strong> Y\u00fcklenen dosyalar\u0131n ge\u00e7ici olarak depolanaca\u011f\u0131 dizini belirtir. B\u00fcy\u00fck dosyalar do\u011frudan bellekte tutulamayaca\u011f\u0131 i\u00e7in, Servlet kapsay\u0131c\u0131s\u0131 bunlar\u0131 belirtilen bu konuma yazar.<br \/>\n    *   <strong>\u00d6nem:<\/strong> Bu dizin, web uygulamas\u0131 taraf\u0131ndan do\u011frudan eri\u015filemeyen, ancak Servlet kapsay\u0131c\u0131s\u0131n\u0131n yazma iznine sahip oldu\u011fu bir yer olmal\u0131d\u0131r. G\u00fcvenlik a\u00e7\u0131s\u0131ndan, bu dizinin web sunucusu taraf\u0131ndan do\u011frudan servis edilmemesi \u00f6nemlidir. Aksi takdirde, ge\u00e7ici olarak depolanan hassas dosyalar veya zararl\u0131 i\u00e7erikler d\u0131\u015far\u0131dan eri\u015filebilir hale gelebilir. Performans i\u00e7in, bu dizinin h\u0131zl\u0131 bir disk \u00fczerinde olmas\u0131 tercih edilir.<br \/>\n    *   <strong>Varsay\u0131lan:<\/strong> Belirtilmezse, Servlet kapsay\u0131c\u0131s\u0131n\u0131n varsay\u0131lan ge\u00e7ici dizini (genellikle <code>\/tmp<\/code> veya uygulama sunucusunun kendi ge\u00e7ici dizini) kullan\u0131l\u0131r.<\/p>\n<p>*   <strong><code>maxFileSize<\/code><\/strong>:<br \/>\n    *   <strong>Ama\u00e7:<\/strong> Tek bir dosyan\u0131n izin verilen maksimum boyutunu bayt cinsinden s\u0131n\u0131rlar.<br \/>\n    *   <strong>\u00d6nem:<\/strong> Bu parametre, hizmet reddi (DoS) sald\u0131r\u0131lar\u0131n\u0131 \u00f6nlemek i\u00e7in kritik \u00f6neme sahiptir. K\u00f6t\u00fc niyetli bir kullan\u0131c\u0131, \u00e7ok b\u00fcy\u00fck dosyalar y\u00fckleyerek sunucunun kaynaklar\u0131n\u0131 t\u00fcketmeye \u00e7al\u0131\u015fabilir. Bu s\u0131n\u0131r, bu t\u00fcr sald\u0131r\u0131lara kar\u015f\u0131 ilk savunma hatt\u0131d\u0131r. E\u011fer y\u00fcklenen bir dosya bu s\u0131n\u0131r\u0131 a\u015farsa, Servlet kapsay\u0131c\u0131s\u0131 <code>javax.servlet.ServletException<\/code> veya <code>IllegalStateException<\/code> f\u0131rlat\u0131r.<br \/>\n    *   <strong>De\u011fer:<\/strong> <code>-1<\/code> s\u0131n\u0131rs\u0131z anlam\u0131na gelir, ancak \u00fcretim ortamlar\u0131nda kesinlikle \u00f6nerilmez.<\/p>\n<p>*   <strong><code>maxRequestSize<\/code><\/strong>:<br \/>\n    *   <strong>Ama\u00e7:<\/strong> T\u00fcm <code>multipart\/form-data<\/code> iste\u011finin (t\u00fcm dosyalar ve di\u011fer form alanlar\u0131 dahil) izin verilen maksimum boyutunu bayt cinsinden s\u0131n\u0131rlar.<br \/>\n    *   <strong>\u00d6nem:<\/strong> <code>maxFileSize<\/code> tek tek dosyalar\u0131 s\u0131n\u0131rlar, <code>maxRequestSize<\/code> ise t\u00fcm iste\u011fi s\u0131n\u0131rlar. Birden fazla dosya y\u00fckleme senaryolar\u0131nda veya \u00e7ok say\u0131da form alan\u0131 i\u00e7eren isteklerde bu parametre \u00f6nemlidir. Yine DoS sald\u0131r\u0131lar\u0131na kar\u015f\u0131 koruma sa\u011flar.<br \/>\n    *   <strong>De\u011fer:<\/strong> <code>-1<\/code> s\u0131n\u0131rs\u0131z anlam\u0131na gelir, ancak \u00fcretim ortamlar\u0131nda kesinlikle \u00f6nerilmez.<\/p>\n<p>*   <strong><code>fileSizeThreshold<\/code><\/strong>:<br \/>\n    *   <strong>Ama\u00e7:<\/strong> Y\u00fcklenen dosyalar\u0131n diske yaz\u0131lmadan \u00f6nce bellekte tutulaca\u011f\u0131 bayt cinsinden e\u015fi\u011fi belirtir.<br \/>\n    *   <strong>\u00d6nem:<\/strong> Bu parametre performans optimizasyonu i\u00e7in kullan\u0131l\u0131r. E\u015fikten daha k\u00fc\u00e7\u00fck dosyalar do\u011frudan bellekte i\u015flenir, bu da disk I\/O&#8217;dan ka\u00e7\u0131narak daha h\u0131zl\u0131 i\u015flem sa\u011flar. E\u015fikten daha b\u00fcy\u00fck dosyalar ise <code>location<\/code> parametresinde belirtilen ge\u00e7ici dizine diske yaz\u0131l\u0131r. Bu, sunucunun belle\u011finin b\u00fcy\u00fck dosyalarla dolmas\u0131n\u0131 \u00f6nler. \u00c7ok d\u00fc\u015f\u00fck bir de\u011fer, s\u0131k disk I\/O&#8217;ya neden olabilirken, \u00e7ok y\u00fcksek bir de\u011fer bellek t\u00fcketimini art\u0131rabilir. Uygulaman\u0131z\u0131n tipik dosya boyutlar\u0131na g\u00f6re optimize edilmelidir.<br \/>\n    *   <strong>Varsay\u0131lan:<\/strong> 0&#8217;d\u0131r, yani t\u00fcm dosyalar do\u011frudan diske yaz\u0131l\u0131r.<\/p>\n<p>Bu parametrelerin do\u011fru \u015fekilde yap\u0131land\u0131r\u0131lmas\u0131, uygulaman\u0131z\u0131n dosya y\u00fckleme \u00f6zelliklerinin g\u00fcvenli, kararl\u0131 ve performansl\u0131 olmas\u0131n\u0131 sa\u011flar.<\/p>\n<h2>Part Aray\u00fcz\u00fc ile Dosya \u0130\u015flemleri<\/h2>\n<p><code>Part<\/code> aray\u00fcz\u00fc, Servlet 3.0 dosya y\u00fckleme API&#8217;sinin kalbinde yer al\u0131r. <code>@MultipartConfig<\/code> anotasyonu sayesinde Servlet kapsay\u0131c\u0131s\u0131 taraf\u0131ndan ayr\u0131\u015ft\u0131r\u0131lan her bir form alan\u0131 veya y\u00fcklenen dosya, bir <code>Part<\/code> nesnesi olarak temsil edilir. Bu nesne, y\u00fcklenen i\u00e7eri\u011fe eri\u015fmek ve onu i\u015flemek i\u00e7in standart bir y\u00f6ntem sa\u011flar.<\/p>\n<h3>Part Nesnesi Elde Etme<\/h3>\n<p><code>HttpServletRequest<\/code> nesnesi \u00fczerinden <code>Part<\/code> nesnelerine eri\u015filir:<br \/>\n*   <code>request.getPart(\"inputFieldName\")<\/code>: Tek bir dosya y\u00fckleme alan\u0131ndan veya belirli bir form alan\u0131ndan gelen <code>Part<\/code> nesnesini almak i\u00e7in kullan\u0131l\u0131r. <code>inputFieldName<\/code>, HTML formundaki <code><input type=\"file\" name=\"inputFieldName\"><\/code> veya <code><input type=\"text\" name=\"inputFieldName\"><\/code> etiketinin <code>name<\/code> \u00f6zniteli\u011fidir.<br \/>\n*   <code>request.getParts()<\/code>: \u0130stekteki t\u00fcm <code>Part<\/code> nesnelerini bir <code>Collection<Part><\/code> olarak d\u00f6nd\u00fcr\u00fcr. Bu, \u00f6zellikle birden fazla dosyan\u0131n y\u00fcklenebildi\u011fi durumlarda veya form alanlar\u0131 ile dosyalar\u0131n birlikte i\u015flenmesi gerekti\u011finde kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<p><strong>\u00d6rnek:<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Tek bir dosya almak\nPart filePart = request.getPart(\"myFile\"); \/\/ \"myFile\" HTML input'un name'i\n\n\/\/ T\u00fcm part'lar\u0131 almak\nCollection<Part> parts = request.getParts();\nfor (Part part : parts) {\n    \/\/ Her bir part'\u0131 i\u015fleyin\n}<\/code><\/pre>\n<h3>Dosya Bilgilerine Eri\u015fim<\/h3>\n<p><code>Part<\/code> nesnesi, y\u00fcklenen dosya hakk\u0131nda \u00e7e\u015fitli bilgilere eri\u015fim sa\u011flar:<br \/>\n*   <code>part.getName()<\/code>: Bu <code>Part<\/code> nesnesinin ad\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr. Bu, HTML formundaki <code><input><\/code> etiketinin <code>name<\/code> \u00f6zniteli\u011fidir. Bir dosya i\u00e7in bu, dosya giri\u015f alan\u0131n\u0131n ad\u0131d\u0131r; bir metin alan\u0131 i\u00e7in ise metin alan\u0131n\u0131n ad\u0131d\u0131r.<br \/>\n*   <code>part.getSubmittedFileName()<\/code>: Y\u00fcklenen dosyan\u0131n orijinal ad\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr. Bu ad, istemci taraf\u0131ndan g\u00f6nderilen add\u0131r ve g\u00fcvenlik nedenleriyle do\u011frudan kullan\u0131lmamal\u0131, temizlenmeli veya yeni bir ad olu\u015fturulmal\u0131d\u0131r.<br \/>\n*   <code>part.getContentType()<\/code>: Y\u00fcklenen dosyan\u0131n MIME t\u00fcr\u00fcn\u00fc (\u00f6rne\u011fin, <code>image\/jpeg<\/code>, <code>application\/pdf<\/code>) d\u00f6nd\u00fcr\u00fcr. Bu, dosya t\u00fcr\u00fc do\u011frulamas\u0131 i\u00e7in kullan\u0131labilir.<br \/>\n*   <code>part.getSize()<\/code>: Y\u00fcklenen dosyan\u0131n boyutunu bayt cinsinden d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <code>part.getInputStream()<\/code>: Dosya i\u00e7eri\u011fini okumak i\u00e7in bir <code>InputStream<\/code> d\u00f6nd\u00fcr\u00fcr. Bu, dosyay\u0131 do\u011frudan i\u015flemek (\u00f6rne\u011fin, veritaban\u0131na kaydetmek, boyutunu de\u011fi\u015ftirmek) veya manuel olarak kaydetmek i\u00e7in kullan\u0131l\u0131r.<\/p>\n<h3>Dosyay\u0131 Kaydetme<\/h3>\n<p>Y\u00fcklenen dosyay\u0131 sunucu diskine kaydetmenin iki ana yolu vard\u0131r:<\/p>\n<p>1.  <strong><code>part.write(String fileName)<\/code> Metodu ile:<\/strong><br \/>\n    Bu metod, <code>Part<\/code> i\u00e7eri\u011fini do\u011frudan belirtilen <code>fileName<\/code> ile diske kaydeder. Dosya, <code>@MultipartConfig<\/code> anotasyonunda belirtilen <code>location<\/code> dizinine (veya varsay\u0131lan ge\u00e7ici dizine) kaydedilir.<\/p>\n<pre><code class=\"language-java\">String fileName = part.getSubmittedFileName(); \/\/ G\u00fcvenli hale getirilmeli!\n    String uploadPath = \"\/path\/to\/upload\/directory\"; \/\/ Kendi sabit y\u00fckleme dizininiz\n    \n    \/\/ G\u00fcvenli dosya ad\u0131 olu\u015fturma (a\u015fa\u011f\u0131da detayland\u0131r\u0131lacak)\n    String safeFileName = getSafeFileName(fileName); \n    \n    part.write(uploadPath + File.separator + safeFileName);<\/code><\/pre>\n<p>    Bu y\u00f6ntem basit ve h\u0131zl\u0131d\u0131r, ancak dosyan\u0131n nereye kaydedilece\u011fi konusunda <code>@MultipartConfig<\/code>&#8216;deki <code>location<\/code> parametresiyle s\u0131n\u0131rl\u0131d\u0131r. E\u011fer dosyay\u0131 belirli bir alt dizine veya farkl\u0131 bir konuma kaydetmek isterseniz, tam yolu <code>write()<\/code> metoduna iletmeniz gerekir.<\/p>\n<p>2.  <strong><code>InputStream<\/code> ile Manuel Kaydetme:<\/strong><br \/>\n    Bu y\u00f6ntem, dosyay\u0131 kaydetme \u00fczerinde daha fazla kontrol sa\u011flar. <code>part.getInputStream()<\/code> ile dosya i\u00e7eri\u011fini bir ak\u0131\u015f olarak al\u0131p, istedi\u011finiz bir konuma <code>FileOutputStream<\/code> kullanarak yazabilirsiniz. Bu, \u00f6zellikle dosyay\u0131 farkl\u0131 bir dizin yap\u0131s\u0131na kaydetmek, dosya ad\u0131n\u0131 dinamik olarak olu\u015fturmak veya dosya i\u00e7eri\u011fi \u00fczerinde ek i\u015flemler yapmak istedi\u011finizde kullan\u0131\u015fl\u0131d\u0131r (\u00f6rne\u011fin, dosya boyutu kontrol\u00fc, vir\u00fcs taramas\u0131 entegrasyonu).<\/p>\n<pre><code class=\"language-java\">String fileName = part.getSubmittedFileName();\n    String uploadPath = \"\/path\/to\/upload\/directory\";\n    String safeFileName = getSafeFileName(fileName);\n    File outputFile = new File(uploadPath + File.separator + safeFileName);\n\n    try (InputStream fileContent = part.getInputStream();\n         FileOutputStream fos = new FileOutputStream(outputFile)) {\n        byte[] buffer = new byte[1024];\n        int bytesRead;\n        while ((bytesRead = fileContent.read(buffer)) != -1) {\n            fos.write(buffer, 0, bytesRead);\n        }\n    } catch (IOException e) {\n        \/\/ Hata y\u00f6netimi\n    }<\/code><\/pre>\n<p><strong>G\u00fcvenli Dosya Adland\u0131rma:<\/strong><br \/>\n<code>getSubmittedFileName()<\/code> metodu taraf\u0131ndan d\u00f6nd\u00fcr\u00fclen dosya ad\u0131, istemci taraf\u0131ndan sa\u011flan\u0131r ve k\u00f6t\u00fc niyetli olabilir (\u00f6rne\u011fin, <code>..\/..\/..\/..\/etc\/passwd<\/code> gibi yol ge\u00e7i\u015f sald\u0131r\u0131lar\u0131). Bu nedenle, bu ad\u0131 do\u011frudan kullanarak dosyay\u0131 kaydetmek son derece tehlikelidir. Dosya ad\u0131n\u0131 temizlemek veya yeni bir benzersiz ad olu\u015fturmak esast\u0131r.<\/p>\n<pre><code class=\"language-java\">private String getSafeFileName(String fileName) {\n    \/\/ Yaln\u0131zca alfan\u00fcmerik karakterleri, tireleri ve noktalar\u0131 koru\n    \/\/ ve yol ge\u00e7i\u015fini engelle\n    String cleanFileName = Paths.get(fileName).getFileName().toString();\n    return cleanFileName.replaceAll(\"[^a-zA-Z0-9.-]\", \"_\");\n}<\/code><\/pre>\n<p>Daha da g\u00fcvenli bir yakla\u015f\u0131m, dosyay\u0131 benzersiz bir UUID (Universally Unique Identifier) ile kaydetmek ve orijinal ad\u0131n\u0131 bir veritaban\u0131nda saklamakt\u0131r.<\/p>\n<h3>Dosya Silme<\/h3>\n<p><code>part.delete()<\/code> metodu, <code>Part<\/code> nesnesiyle ili\u015fkili ge\u00e7ici depolama kaynaklar\u0131n\u0131 (e\u011fer dosya diske yaz\u0131lm\u0131\u015fsa) siler. Servlet kapsay\u0131c\u0131s\u0131, istek tamamland\u0131\u011f\u0131nda genellikle bu temizli\u011fi otomatik olarak yapar. Ancak, belirli durumlarda (\u00f6rne\u011fin, bir hata durumunda veya dosyan\u0131n i\u015flenmesi tamamland\u0131ktan sonra ge\u00e7ici dosyay\u0131 hemen kald\u0131rmak istedi\u011finizde) manuel olarak \u00e7a\u011fr\u0131labilir.<\/p>\n<h3>Header Bilgilerine Eri\u015fim<\/h3>\n<p><code>Part<\/code> nesnesi, dosya veya form alan\u0131yla ilgili HTTP ba\u015fl\u0131klar\u0131na da eri\u015fim sa\u011flar:<br \/>\n*   <code>part.getHeader(\"Content-Disposition\")<\/code>: <code>Content-Disposition<\/code> ba\u015fl\u0131\u011f\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr. Bu ba\u015fl\u0131k, <code>name<\/code> ve <code>filename<\/code> gibi bilgileri i\u00e7erir.<br \/>\n*   <code>part.getHeaders(\"Content-Type\")<\/code>: <code>Content-Type<\/code> ba\u015fl\u0131\u011f\u0131n\u0131 d\u00f6nd\u00fcr\u00fcr.<\/p>\n<p>Bu metotlar, \u00f6zellikle <code>Content-Disposition<\/code> ba\u015fl\u0131\u011f\u0131ndaki <code>filename<\/code> \u00f6zniteli\u011fini ayr\u0131\u015ft\u0131rarak orijinal dosya ad\u0131n\u0131 almak i\u00e7in kullan\u0131labilir, ancak <code>getSubmittedFileName()<\/code> genellikle daha basit bir alternatiftir.<\/p>\n<p><code>Part<\/code> aray\u00fcz\u00fc, Servlet 3.0 ile gelen en \u00f6nemli geli\u015ftirmelerden biridir. Geli\u015ftiricilere, <code>multipart\/form-data<\/code> isteklerini kolayca i\u015flemleri i\u00e7in g\u00fc\u00e7l\u00fc ve standart bir API sunar.<\/p>\n<h2>U\u00e7tan Uca Bir Dosya Y\u00fckleme Uygulamas\u0131<\/h2>\n<p>\u015eimdiye kadar \u00f6\u011frendiklerimizi bir araya getirerek, Servlet 3.0 ile basit bir dosya y\u00fckleme uygulamas\u0131n\u0131n nas\u0131l olu\u015fturulaca\u011f\u0131n\u0131 g\u00f6sterelim. Bu \u00f6rnek, bir HTML formu ve bu formu i\u015fleyecek bir Servlet&#8217;ten olu\u015facakt\u0131r.<\/p>\n<h3>HTML Formu Olu\u015fturma<\/h3>\n<p>Dosya y\u00fckleme i\u00e7in, HTML formunun <code>method<\/code> \u00f6zniteli\u011fi <code>POST<\/code> olmal\u0131 ve <code>enctype<\/code> \u00f6zniteli\u011fi <code>multipart\/form-data<\/code> olarak ayarlanmal\u0131d\u0131r. <code><input type=\"file\"><\/code> etiketi, dosya se\u00e7imi i\u00e7in kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-html\"><!DOCTYPE html>\n<html lang=\"tr\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Dosya Y\u00fckleme \u00d6rne\u011fi<\/title>\n    <style>\n        body { font-family: Arial, sans-serif; margin: 20px; }\n        form { border: 1px solid #ccc; padding: 20px; border-radius: 5px; max-width: 500px; margin: auto; }\n        label { display: block; margin-bottom: 5px; font-weight: bold; }\n        input[type=\"text\"], input[type=\"file\"] { width: calc(100% - 22px); padding: 8px; margin-bottom: 10px; border: 1px solid #ddd; border-radius: 3px; }\n        input[type=\"submit\"] { background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 3px; cursor: pointer; font-size: 16px; }\n        input[type=\"submit\"]:hover { background-color: #45a049; }\n        .message { margin-top: 20px; padding: 10px; border-radius: 5px; }\n        .success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }\n        .error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }\n    <\/style>\n<\/head>\n<body>\n    <form action=\"uploadServlet\" method=\"post\" enctype=\"multipart\/form-data\">\n        <h2>Dosya Y\u00fckleme Formu<\/h2>\n        <label for=\"description\">A\u00e7\u0131klama:<\/label>\n        <input type=\"text\" id=\"description\" name=\"description\" required><br>\n\n        <label for=\"file\">Y\u00fcklenecek Dosya:<\/label>\n        <input type=\"file\" id=\"file\" name=\"file\" required><br>\n\n        <input type=\"submit\" value=\"Y\u00fckle\">\n    <\/form>\n\n    <% \n        String message = (String) request.getAttribute(\"message\");\n        String messageType = (String) request.getAttribute(\"messageType\");\n        if (message != null &#038;&#038; !message.isEmpty()) {\n    %>\n        <div class=\"message <%= messageType %>\">\n            <%= message %>\n        <\/div>\n    <%\n        }\n    %>\n<\/body>\n<\/html><\/code><\/pre>\n<p>Bu form, bir metin alan\u0131 (<code>description<\/code>) ve bir dosya y\u00fckleme alan\u0131 (<code>file<\/code>) i\u00e7erir. Form g\u00f6nderildi\u011finde, <code>uploadServlet<\/code> adl\u0131 Servlet taraf\u0131ndan i\u015flenecektir.<\/p>\n<h3>Servlet Olu\u015fturma<\/h3>\n<p>\u015eimdi bu formu i\u015fleyecek Servlet&#8217;i olu\u015ftural\u0131m.<\/p>\n<pre><code class=\"language-java\">import javax.servlet.ServletException;\nimport javax.servlet.annotation.MultipartConfig;\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.servlet.http.Part;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.UUID; \/\/ Benzersiz dosya adlar\u0131 i\u00e7in\n\n@WebServlet(\"\/uploadServlet\")\n@MultipartConfig(\n    fileSizeThreshold = 1024 <em> 1024 <\/em> 2, \/\/ 2MB\n    maxFileSize = 1024 <em> 1024 <\/em> 10,      \/\/ 10MB\n    maxRequestSize = 1024 <em> 1024 <\/em> 50,   \/\/ 50MB\n    location = \"\/tmp\/uploads\"            \/\/ Ge\u00e7ici dosya depolama yolu\n)\npublic class FileUploadServlet extends HttpServlet {\n\n    private static final String UPLOAD_DIRECTORY = \"uploaded_files\"; \/\/ Kal\u0131c\u0131 y\u00fckleme dizini\n\n    @Override\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) \n            throws ServletException, IOException {\n\n        String uploadPath = getServletContext().getRealPath(\"\") \n                          + File.separator + UPLOAD_DIRECTORY;\n        \n        \/\/ Y\u00fckleme dizini mevcut de\u011filse olu\u015ftur\n        File uploadDir = new File(uploadPath);\n        if (!uploadDir.exists()) {\n            uploadDir.mkdir();\n        }\n\n        String message = \"\";\n        String messageType = \"error\"; \/\/ Varsay\u0131lan hata\n\n        try {\n            \/\/ Form alan\u0131n\u0131 al\n            String description = request.getParameter(\"description\");\n            if (description == null || description.trim().isEmpty()) {\n                throw new IllegalArgumentException(\"A\u00e7\u0131klama alan\u0131 bo\u015f olamaz.\");\n            }\n            System.out.println(\"A\u00e7\u0131klama: \" + description);\n\n            \/\/ Dosya Part'\u0131n\u0131 al\n            Part filePart = request.getPart(\"file\"); \n            \n            \/\/ Dosya Part'\u0131n\u0131n null olup olmad\u0131\u011f\u0131n\u0131 kontrol et\n            if (filePart == null || filePart.getSize() == 0) {\n                throw new IllegalArgumentException(\"Y\u00fcklenecek dosya se\u00e7ilmedi veya bo\u015f.\");\n            }\n\n            String originalFileName = filePart.getSubmittedFileName();\n            if (originalFileName == null || originalFileName.trim().isEmpty()) {\n                 throw new IllegalArgumentException(\"Dosya ad\u0131 al\u0131namad\u0131.\");\n            }\n\n            \/\/ Dosya ad\u0131n\u0131 g\u00fcvenli hale getir ve benzersiz bir ad olu\u015ftur\n            String fileExtension = \"\";\n            int dotIndex = originalFileName.lastIndexOf('.');\n            if (dotIndex > 0 && dotIndex < originalFileName.length() - 1) {\n                fileExtension = originalFileName.substring(dotIndex);\n            }\n            String uniqueFileName = UUID.randomUUID().toString() + fileExtension;\n            \n            \/\/ Dosyan\u0131n kaydedilece\u011fi tam yol\n            String filePath = uploadPath + File.separator + uniqueFileName;\n            \n            \/\/ Dosyay\u0131 diske kaydet\n            \/\/ part.write() metodunu kullanmak daha basit olabilir,\n            \/\/ ancak manuel InputStream kullan\u0131m\u0131 daha fazla kontrol sa\u011flar.\n            try (InputStream fileContent = filePart.getInputStream()) {\n                Files.copy(fileContent, Paths.get(filePath));\n            }\n            \n            \/\/ Ba\u015far\u0131l\u0131 mesaj\u0131\n            message = \"Dosya ba\u015far\u0131yla y\u00fcklendi! Dosya Ad\u0131: \" + originalFileName + \n                      \", Sunucudaki Ad\u0131: \" + uniqueFileName + \n                      \", Boyut: \" + (filePart.getSize() \/ 1024) + \" KB\";\n            messageType = \"success\";\n\n        } catch (IllegalArgumentException e) {\n            message = \"Y\u00fckleme hatas\u0131: \" + e.getMessage();\n        } catch (ServletException e) {\n            \/\/ @MultipartConfig limitleri a\u015f\u0131ld\u0131\u011f\u0131nda veya ba\u015fka bir Servlet hatas\u0131\n            if (e.getCause() instanceof IllegalStateException) {\n                message = \"Y\u00fckleme hatas\u0131: Dosya boyutu veya istek boyutu limitleri a\u015f\u0131ld\u0131. \" + e.getCause().getMessage();\n            } else {\n                message = \"Sunucu hatas\u0131 olu\u015ftu: \" + e.getMessage();\n            }\n            e.printStackTrace(); \/\/ Hata detaylar\u0131n\u0131 logla\n        } catch (IOException e) {\n            message = \"Dosya kaydetme hatas\u0131: \" + e.getMessage();\n            e.printStackTrace(); \/\/ Hata detaylar\u0131n\u0131 logla\n        } catch (Exception e) {\n            message = \"Beklenmeyen bir hata olu\u015ftu: \" + e.getMessage();\n            e.printStackTrace(); \/\/ Hata detaylar\u0131n\u0131 logla\n        } finally {\n            \/\/ Y\u00fckleme tamamland\u0131ktan sonra ge\u00e7ici dosyalar\u0131 sil (iste\u011fe ba\u011fl\u0131, kapsay\u0131c\u0131 genellikle yapar)\n            \/\/ for (Part part : request.getParts()) {\n            \/\/     part.delete(); \n            \/\/ }\n        }\n\n        request.setAttribute(\"message\", message);\n        request.setAttribute(\"messageType\", messageType);\n        getServletContext().getRequestDispatcher(\"\/index.jsp\").forward(request, response);\n    }\n}<\/code><\/pre>\n<p>Bu Servlet:<br \/>\n1.  <code>@WebServlet<\/code> ile <code>\/uploadServlet<\/code> URL'sine e\u015flenmi\u015ftir.<br \/>\n2.  <code>@MultipartConfig<\/code> ile dosya y\u00fckleme s\u0131n\u0131rlar\u0131 ve ge\u00e7ici depolama konumu belirtilmi\u015ftir.<br \/>\n3.  <code>doPost<\/code> metodunda, gelen <code>multipart\/form-data<\/code> iste\u011fini i\u015fler.<br \/>\n4.  <code>request.getParameter(\"description\")<\/code> ile metin alan\u0131n\u0131 al\u0131r.<br \/>\n5.  <code>request.getPart(\"file\")<\/code> ile y\u00fcklenen dosyan\u0131n <code>Part<\/code> nesnesini al\u0131r.<br \/>\n6.  <code>getSubmittedFileName()<\/code> ile orijinal dosya ad\u0131n\u0131 al\u0131r.<br \/>\n7.  <code>UUID.randomUUID().toString()<\/code> kullanarak dosyaya benzersiz bir ad verir, b\u00f6ylece ad \u00e7ak\u0131\u015fmalar\u0131 ve g\u00fcvenlik sorunlar\u0131 \u00f6nlenir.<br \/>\n8.  <code>Files.copy()<\/code> kullanarak <code>InputStream<\/code>'den dosyay\u0131 kal\u0131c\u0131 bir dizine kaydeder. <code>getServletContext().getRealPath(\"\")<\/code> uygulamam\u0131z\u0131n k\u00f6k dizinini verir, <code>UPLOAD_DIRECTORY<\/code> ise bu k\u00f6k dizin alt\u0131nda dosyalar\u0131n depolanaca\u011f\u0131 klas\u00f6rd\u00fcr.<br \/>\n9.  Ba\u015far\u0131 veya hata mesajlar\u0131n\u0131 JSP sayfas\u0131na iletir.<\/p>\n<h2>G\u00fcvenlik ve Performans Konular\u0131<\/h2>\n<p>Dosya y\u00fckleme i\u015flemleri, web uygulamalar\u0131nda \u00f6nemli g\u00fcvenlik ve performans riskleri ta\u015f\u0131yan alanlardan biridir. Bu riskleri minimize etmek i\u00e7in dikkatli bir yakla\u015f\u0131m gereklidir.<\/p>\n<h3>Dosya Ad\u0131 G\u00fcvenli\u011fi (Path Traversal)<\/h3>\n<p>*   <strong>Risk:<\/strong> K\u00f6t\u00fc niyetli kullan\u0131c\u0131lar, <code>..\/..\/..\/..\/etc\/passwd<\/code> gibi dosya adlar\u0131 g\u00f6ndererek sunucu dosya sisteminde istenmeyen yerlere dosya yazmaya \u00e7al\u0131\u015fabilirler.<br \/>\n*   <strong>\u00d6nlem:<\/strong> <code>part.getSubmittedFileName()<\/code> taraf\u0131ndan d\u00f6nd\u00fcr\u00fclen dosya ad\u0131n\u0131 do\u011frudan kullanmay\u0131n.<br \/>\n    *   Yaln\u0131zca dosya ad\u0131n\u0131 ay\u0131klay\u0131n (<code>Paths.get(fileName).getFileName().toString()<\/code>).<br \/>\n    *   Dosya ad\u0131n\u0131 temizleyin: Ge\u00e7ersiz karakterleri kald\u0131r\u0131n veya izin verilen karakterlerle s\u0131n\u0131rlay\u0131n.<br \/>\n    *   En g\u00fcvenli y\u00f6ntem, dosyay\u0131 benzersiz bir adla (\u00f6rne\u011fin, UUID kullanarak) kaydetmek ve orijinal ad\u0131n\u0131 veritaban\u0131nda saklamakt\u0131r.<\/p>\n<h3>Dosya Boyutu S\u0131n\u0131rlamalar\u0131<\/h3>\n<p>*   <strong>Risk:<\/strong> \u00c7ok b\u00fcy\u00fck dosyalar\u0131n y\u00fcklenmesine izin vermek, sunucunun belle\u011fini ve disk alan\u0131n\u0131 t\u00fcketerek hizmet reddi (DoS) sald\u0131r\u0131lar\u0131na yol a\u00e7abilir.<br \/>\n*   <strong>\u00d6nlem:<\/strong> <code>@MultipartConfig<\/code> anotasyonundaki <code>maxFileSize<\/code> (tek dosya i\u00e7in) ve <code>maxRequestSize<\/code> (t\u00fcm istek i\u00e7in) parametrelerini mutlaka yap\u0131land\u0131r\u0131n. Bu s\u0131n\u0131rlar, Servlet kapsay\u0131c\u0131s\u0131 seviyesinde uyguland\u0131\u011f\u0131 i\u00e7in erken a\u015famada b\u00fcy\u00fck istekleri reddeder.<\/p>\n<h3>Dosya T\u00fcr\u00fc Do\u011frulama<\/h3>\n<p>*   <strong>Risk:<\/strong> Kullan\u0131c\u0131lar\u0131n y\u00fcr\u00fct\u00fclebilir dosyalar (\u00f6rne\u011fin, <code>.exe<\/code>, <code>.php<\/code>, <code>.jsp<\/code>) veya zararl\u0131 komut dosyalar\u0131 y\u00fcklemesine izin vermek, sunucuya arka kap\u0131lar a\u00e7abilir veya web sitesini tehlikeye atabilir.<br \/>\n*   <strong>\u00d6nlem:<\/strong><br \/>\n    *   <strong>MIME T\u00fcr\u00fc Kontrol\u00fc:<\/strong> <code>part.getContentType()<\/code> metodunu kullanarak dosyan\u0131n MIME t\u00fcr\u00fcn\u00fc kontrol edin. Yaln\u0131zca izin verilen t\u00fcrleri (\u00f6rne\u011fin, <code>image\/jpeg<\/code>, <code>application\/pdf<\/code>) kabul edin. Ancak, MIME t\u00fcr\u00fcn\u00fcn istemci taraf\u0131ndan kolayca taklit edilebilece\u011fini unutmay\u0131n.<br \/>\n    *   <strong>Dosya Uzant\u0131s\u0131 Kontrol\u00fc:<\/strong> Dosya uzant\u0131s\u0131n\u0131 kontrol edin. Yaln\u0131zca beyaz listeye al\u0131nm\u0131\u015f uzant\u0131lara izin verin.<br \/>\n    *   <strong>Ger\u00e7ek Dosya \u0130\u00e7eri\u011fi Kontrol\u00fc:<\/strong> En g\u00fcvenli y\u00f6ntem, dosyan\u0131n ilk birka\u00e7 bayt\u0131n\u0131 okuyarak (Magic Number) ger\u00e7ek dosya t\u00fcr\u00fcn\u00fc belirlemektir. Bu, uzant\u0131 ve MIME t\u00fcr\u00fc sahtekarl\u0131\u011f\u0131n\u0131 \u00f6nler.<\/p>\n<h3>Antivir\u00fcs Taramas\u0131<\/h3>\n<p>*   <strong>Risk:<\/strong> Y\u00fcklenen dosyalar zararl\u0131 yaz\u0131l\u0131m (vir\u00fcs, truva at\u0131 vb.) i\u00e7erebilir. Bu dosyalar\u0131n sunucuya kaydedilmesi veya di\u011fer kullan\u0131c\u0131lara sunulmas\u0131 ciddi g\u00fcvenlik riskleri olu\u015fturur.<br \/>\n*   <strong>\u00d6nlem:<\/strong> Y\u00fcklenen dosyalar\u0131 sunucuya kaydettikten sonra, bir antivir\u00fcs yaz\u0131l\u0131m\u0131 veya servisi ile taramak iyi bir uygulamad\u0131r.<\/p>\n<h3>Depolama Yolu<\/h3>\n<p>*   <strong>Risk:<\/strong> Y\u00fcklenen dosyalar\u0131 uygulaman\u0131n web k\u00f6k dizinine (\u00f6rne\u011fin, <code>webapp<\/code> klas\u00f6r\u00fc alt\u0131na) kaydetmek, do\u011frudan URL \u00fczerinden eri\u015filebilir olmalar\u0131na neden olabilir. Bu, zararl\u0131 komut dosyalar\u0131n\u0131n \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131na veya hassas verilerin a\u00e7\u0131\u011fa \u00e7\u0131kmas\u0131na yol a\u00e7abilir.<br \/>\n*   <strong>\u00d6nlem:<\/strong> Y\u00fcklenen dosyalar\u0131 web sunucusu taraf\u0131ndan do\u011frudan eri\u015filemeyen (ancak uygulaman\u0131z\u0131n eri\u015febilece\u011fi) bir dizine kaydedin. Dosyalara eri\u015fim gerekti\u011finde, bunlar\u0131 bir Servlet veya denetleyici arac\u0131l\u0131\u011f\u0131yla g\u00fcvenli bir \u015fekilde sunun.<\/p>\n<h3>Bellek ve Disk Kullan\u0131m\u0131<\/h3>\n<p>*   <strong>Performans:<\/strong> <code>fileSizeThreshold<\/code> parametresi, k\u00fc\u00e7\u00fck dosyalar\u0131n bellekte tutulmas\u0131n\u0131 sa\u011flayarak disk I\/O'dan ka\u00e7\u0131n\u0131r ve performans\u0131 art\u0131r\u0131r. Ancak \u00e7ok b\u00fcy\u00fck bir e\u015fik, bellek t\u00fckenmesine neden olabilir.<br \/>\n*   <strong>Temizlik:<\/strong> Servlet kapsay\u0131c\u0131s\u0131 genellikle ge\u00e7ici dosyalar\u0131 otomatik olarak temizler. Ancak, uygulaman\u0131z\u0131n kararl\u0131l\u0131\u011f\u0131 i\u00e7in <code>part.delete()<\/code> metodunu kullanarak ge\u00e7ici dosyalar\u0131 manuel olarak temizlemeyi d\u00fc\u015f\u00fcnebilirsiniz, \u00f6zellikle hata durumlar\u0131nda.<\/p>\n<p>Bu g\u00fcvenlik ve performans konular\u0131na dikkat etmek, dosya y\u00fckleme \u00f6zelli\u011fini bar\u0131nd\u0131ran web uygulamalar\u0131n\u0131z\u0131n sa\u011flaml\u0131\u011f\u0131n\u0131 ve g\u00fcvenilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131racakt\u0131r.<\/p>\n<h2>Geli\u015fmi\u015f Senaryolar ve Alternatifler<\/h2>\n<p>Servlet 3.0 dosya y\u00fckleme API'si \u00e7o\u011fu senaryo i\u00e7in yeterli olsa da, baz\u0131 geli\u015fmi\u015f durumlar veya alternatif yakla\u015f\u0131mlar da mevcuttur.<\/p>\n<h3>Birden Fazla Dosya Y\u00fckleme<\/h3>\n<p>HTML formunda birden fazla dosya se\u00e7imine izin vermek i\u00e7in <code><input type=\"file\" name=\"file\" multiple><\/code> \u00f6zniteli\u011fi kullan\u0131l\u0131r. Servlet taraf\u0131nda ise <code>request.getParts()<\/code> metodunu kullanarak t\u00fcm <code>Part<\/code> nesnelerini al\u0131p, her birini d\u00f6ng\u00fc i\u00e7inde i\u015flemek gerekir. Formda hem dosya hem de metin alanlar\u0131 varsa, <code>part.getSubmittedFileName()<\/code> metodunun <code>null<\/code> olup olmad\u0131\u011f\u0131n\u0131 kontrol ederek dosya ve metin alanlar\u0131n\u0131 ay\u0131rabilirsiniz.<\/p>\n<pre><code class=\"language-java\">\/\/ Servlet'te\nfor (Part part : request.getParts()) {\n    String fileName = part.getSubmittedFileName();\n    if (fileName != null && !fileName.isEmpty()) {\n        \/\/ Bu bir dosya Part'\u0131d\u0131r, kaydetme i\u015flemini yap\n        \/\/ ... (yukar\u0131daki \u00f6rnekteki gibi)\n    } else {\n        \/\/ Bu bir form alan\u0131 Part'\u0131d\u0131r (\u00f6rne\u011fin, description)\n        String fieldName = part.getName();\n        String fieldValue = new BufferedReader(new InputStreamReader(part.getInputStream())).readLine();\n        System.out.println(fieldName + \": \" + fieldValue);\n    }\n}<\/code><\/pre>\n<h3>Form Alanlar\u0131 ile Birlikte Dosya Y\u00fckleme<\/h3>\n<p>Yukar\u0131daki \u00f6rnekte g\u00f6sterildi\u011fi gibi, <code>multipart\/form-data<\/code> iste\u011fi hem dosya hem de normal form alanlar\u0131n\u0131 i\u00e7erebilir. <code>request.getParameter()<\/code> metodunu kullanarak normal form alanlar\u0131na eri\u015fmeye devam edebilirsiniz. Ancak, <code>getPart()<\/code> veya <code>getParts()<\/code> ile <code>Part<\/code> nesnelerini ald\u0131ktan sonra <code>request.getParameter()<\/code> \u00e7a\u011fr\u0131s\u0131 yaparsan\u0131z, Servlet kapsay\u0131c\u0131s\u0131 iste\u011fi zaten ayr\u0131\u015ft\u0131rd\u0131\u011f\u0131 i\u00e7in <code>getParameter()<\/code> metodu <code>null<\/code> d\u00f6nd\u00fcrebilir. En iyi uygulama, t\u00fcm form verilerini <code>Part<\/code> nesneleri \u00fczerinden i\u015flemektir.<\/p>\n<h3>Asenkron Dosya Y\u00fckleme (Servlet 3.1+)<\/h3>\n<p>Servlet 3.1 ile birlikte asenkron i\u015flem yetenekleri daha da geli\u015ftirilmi\u015ftir. B\u00fcy\u00fck dosyalar\u0131n y\u00fcklenmesi, uzun s\u00fcren bir i\u015flem olabilir ve bu s\u00fcre boyunca iste\u011fi i\u015fleyen i\u015f par\u00e7ac\u0131\u011f\u0131n\u0131 (thread) bloke edebilir. Asenkron Servlet'ler, bu t\u00fcr uzun s\u00fcreli i\u015flemleri arka planda y\u00fcr\u00fct\u00fcrken i\u015f par\u00e7ac\u0131\u011f\u0131n\u0131 serbest b\u0131rakarak sunucu kaynaklar\u0131n\u0131n daha verimli kullan\u0131lmas\u0131na olanak tan\u0131r.<br \/>\n<code>request.startAsync()<\/code> ve <code>AsyncContext<\/code> nesnesi kullan\u0131larak dosya y\u00fckleme i\u015flemi asenkron hale getirilebilir. Bu, \u00f6zellikle y\u00fcksek e\u015fzamanl\u0131l\u0131k gerektiren uygulamalar i\u00e7in faydal\u0131d\u0131r.<\/p>\n<h3>Spring Framework veya Di\u011fer K\u00fct\u00fcphanelerle Entegrasyon<\/h3>\n<p>Bir\u00e7ok modern Java web \u00e7er\u00e7evesi (\u00f6rne\u011fin, Spring MVC), Servlet 3.0 API'sini temel alarak dosya y\u00fckleme i\u00e7in daha y\u00fcksek seviyeli ve entegre \u00e7\u00f6z\u00fcmler sunar. Spring'de <code>MultipartFile<\/code> aray\u00fcz\u00fc ve <code>CommonsMultipartResolver<\/code> veya <code>StandardServletMultipartResolver<\/code> gibi \u00e7\u00f6z\u00fcmler, <code>@RequestParam<\/code> anotasyonu ile dosya y\u00fcklemeyi \u00e7ok daha basit hale getirir. Bu \u00e7er\u00e7eveler, genellikle Servlet 3.0'\u0131n <code>@MultipartConfig<\/code> ve <code>Part<\/code> mekanizmalar\u0131n\u0131 arka planda kullanarak geli\u015ftiricilere daha soyut bir API sunar. E\u011fer bir \u00e7er\u00e7eve kullan\u0131yorsan\u0131z, o \u00e7er\u00e7evenin sundu\u011fu dosya y\u00fckleme mekanizmalar\u0131n\u0131 tercih etmek, genellikle daha kolay entegrasyon ve daha az boilerplate kod anlam\u0131na gelir.<\/p>\n<p>Bu geli\u015fmi\u015f senaryolar ve alternatifler, uygulaman\u0131z\u0131n \u00f6zel ihtiya\u00e7lar\u0131na g\u00f6re dosya y\u00fckleme \u00e7\u00f6z\u00fcm\u00fcn\u00fcz\u00fc daha da optimize etmenize ve geni\u015fletmenize olanak tan\u0131r.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Servlet 3.0 ile birlikte gelen <code>@MultipartConfig<\/code> anotasyonu ve <code>Part<\/code> aray\u00fcz\u00fc, Java web uygulamalar\u0131nda dosya y\u00fckleme i\u015flemini k\u00f6kten basitle\u015ftirmi\u015f ve standartla\u015ft\u0131rm\u0131\u015ft\u0131r. Bu yenilikler, geli\u015ftiricilerin Apache Commons FileUpload gibi \u00fc\u00e7\u00fcnc\u00fc taraf k\u00fct\u00fcphanelere olan ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n\u0131 azaltarak, dosya y\u00fckleme mant\u0131\u011f\u0131n\u0131 do\u011frudan Servlet API'si \u00fczerinden y\u00f6netmelerine olanak tan\u0131m\u0131\u015ft\u0131r.<\/p>\n<p>Art\u0131k geli\u015ftiriciler, HTTP iste\u011finin karma\u015f\u0131k <code>multipart\/form-data<\/code> format\u0131n\u0131 manuel olarak ayr\u0131\u015ft\u0131rmak zorunda kalmadan, deklaratif <code>@MultipartConfig<\/code> anotasyonu ile y\u00fckleme parametrelerini kolayca yap\u0131land\u0131rabilir ve <code>HttpServletRequest.getPart()<\/code> veya <code>HttpServletRequest.getParts()<\/code> metotlar\u0131 arac\u0131l\u0131\u011f\u0131yla y\u00fcklenen dosyalara ve form alanlar\u0131na <code>Part<\/code> nesneleri olarak eri\u015febilirler. <code>Part<\/code> aray\u00fcz\u00fc, dosya ad\u0131n\u0131, boyutunu, MIME t\u00fcr\u00fcn\u00fc ve i\u00e7eri\u011fini bir <code>InputStream<\/code> olarak veya do\u011frudan diske yazmak i\u00e7in basit metotlar sunar.<\/p>\n<p>Bu standart API, sadece geli\u015ftirme s\u00fcrecini h\u0131zland\u0131rmakla kalmaz, ayn\u0131 zamanda dosya boyutu s\u0131n\u0131rlamalar\u0131, ge\u00e7ici depolama y\u00f6netimi ve temel g\u00fcvenlik kontrolleri gibi \u00f6nemli i\u015flevleri Servlet kapsay\u0131c\u0131s\u0131n\u0131n sorumlulu\u011funa b\u0131rakarak uygulamalar\u0131n daha g\u00fcvenli ve kararl\u0131 olmas\u0131n\u0131 sa\u011flar. Ancak, bu kolayl\u0131klar g\u00fcvenlik ve performans konular\u0131n\u0131n g\u00f6z ard\u0131 edilece\u011fi anlam\u0131na gelmez. Dosya ad\u0131 temizli\u011fi, dosya t\u00fcr\u00fc do\u011frulamas\u0131, antivir\u00fcs taramas\u0131 ve do\u011fru depolama stratejileri gibi ek g\u00fcvenlik \u00f6nlemleri, her zaman g\u00f6z \u00f6n\u00fcnde bulundurulmal\u0131d\u0131r.<\/p>\n<p>\u00d6zetle, Servlet 3.0'\u0131n dosya y\u00fckleme API'si, modern Java web uygulamalar\u0131 i\u00e7in g\u00fc\u00e7l\u00fc, esnek ve standart bir \u00e7\u00f6z\u00fcm sunmaktad\u0131r. Geli\u015ftiriciler, bu API'yi etkin bir \u015fekilde kullanarak, kullan\u0131c\u0131lar\u0131na g\u00fcvenli, verimli ve zenginle\u015ftirilmi\u015f dosya y\u00fckleme deneyimleri sa\u011flayabilirler. Gelecekteki Servlet s\u00fcr\u00fcmleri ve ek teknolojilerle birlikte, dosya y\u00fckleme yetenekleri daha da geli\u015ferek, asenkron i\u015flemler ve bulut tabanl\u0131 depolama entegrasyonlar\u0131 gibi daha karma\u015f\u0131k senaryolar\u0131 desteklemeye devam edecektir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler\nGiri\u015f: Web Uygulamalar\u0131nda Dosya Y\u00fcklemenin \u00d6nemi\nModern w","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-32426","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler\" \/>\n<meta property=\"og:description\" content=\"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler Giri\u015f: Web Uygulamalar\u0131nda Dosya Y\u00fcklemenin \u00d6nemi Modern w\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-21T12:41:30+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"26 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler\",\"datePublished\":\"2025-10-21T12:41:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\"},\"wordCount\":4254,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\",\"name\":\"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-21T12:41:30+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/","og_locale":"tr_TR","og_type":"article","og_title":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler","og_description":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler Giri\u015f: Web Uygulamalar\u0131nda Dosya Y\u00fcklemenin \u00d6nemi Modern w","og_url":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-21T12:41:30+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"26 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler","datePublished":"2025-10-21T12:41:30+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/"},"wordCount":4254,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/","url":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/","name":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-21T12:41:30+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/servlet-3-dosya-yukleme-multipartconfig-ve-part-arayuzu-ile-gelismis-yontemler\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Servlet 3 Dosya Y\u00fckleme: @MultipartConfig ve Part Aray\u00fcz\u00fc ile Geli\u015fmi\u015f Y\u00f6ntemler"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=32426"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32426\/revisions"}],"predecessor-version":[{"id":32427,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32426\/revisions\/32427"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=32426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=32426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=32426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}