6 Nisan 2017 Perşembe

Spring 4 MVC jQuery ile AJAX CRUD İşlemleri

            Spring MVC ve jQuery ile %100 Ajax İşlemleri Nasıl Yapılabilir?




Başla

Spring MVC jQuery AJAX Kullanımı

Spring MVC Ajax işlemleri nasıl yapılabilir. Json veri nasıl gönderilir ve işlenir. Bakalım.

Projenin son hali aşağıdaki gibi olacak. Sayfanın tamamını yenilemeden ekleme, güncelleme ve silme işlemleri gerçekleştirilecek.


Kullanılan Teknolojiler

  • Spring MVC 4.1.6.RELEASE
  • Maven 4
  • JDK 1.8
  • Jackson Library
  • JSTL 1.2
  • Bootstrap
  • jQuery


Adım 1 :

Maven projesi oluşturalım. Java Based Configuration Gerekli bağımlılıkları ekleyelim. Json' dan Java nesnesine veya tam tersine dönüşüm yapmak için Jackson lib. kullanıyoruz.

Kapsamı provided kütüphaneler zaten servlet container(tomcat vb.) tarafından çalışma zamanında( runtime) sağlanıyor. Derleme için kullanılıyor.

        
            org.springframework
            spring-webmvc
            4.1.6.RELEASE
        
        
            org.springframework
            spring-web
            4.1.6.RELEASE
        
          
            javax.servlet  
            javax.servlet-api  
            3.0.1  
            provided 
         
          
            jstl  
            jstl  
            1.2  
        
        
            com.fasterxml.jackson.core
            jackson-core
            2.4.1
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.4.1.1
        



Adım 2 :

Model sınıfını tanımlayalım.


public class Person {
    
    private int id;
    private String name;
    private int age;
    
    /*setters getters*/
}


Adım 3 :

Kullanacağımız bazı metotları tanımlıyoruz. Sahte( dummy) data acces layer bu arayüzden oluşacak.


public interface PersonDAO {
    public  void insert(Person p);
    public  List<Person> getAllPerson();
    public  void update(Person person);
    public  void remove(int id);   
}

Adım 4 :

Uygulamayı test etmek için sahte( dummy) data acces layer oluşturuyoruz.


@Repository
public class PersonDAOImpl implements PersonDAO{
    
    private static final List<Person> myPersons = new ArrayList<>();
    
    static int id = 4;
    
    static { 
        myPersons.add(new Person(1, "Person1", 14));
        myPersons.add(new Person(2, "Person2", 24));
        myPersons.add(new Person(3, "Person3", 34));
        myPersons.add(new Person(4, "Person4", 45));
    }
    
    @Override
    public  void insert(Person p) {
        p.setId(++id);
        myPersons.add(p);
    }
    
    @Override
    public  void remove(int id) {
        myPersons.stream()
            .filter(p -> p.getId()==id)
            .findFirst()
            .map(p -> myPersons.remove(p));
    }
    
    @Override
    public void update(Person person) {
        myPersons.stream()
            .filter(p -> p.getId() == person.getId())
            .findFirst()
            .map(newP -> {
                newP.setName(person.getName());
                newP.setAge(person.getAge());
                return newP;
            });
       
    }
    
    @Override
    public  List<Person> getAllPerson(){
        return myPersons;
    }
}


Adım 5 :

Url eşlemelerine göre HTTP isteklerine karşılık verecek controller sınıfını yazıyoruz.

  • @Autowired ile PersonDAO' nun implement sınıfının örneği( PersonDAOImpl), otomatik oluşturulur(Inject).
  • @RequestMapping url-http istekleriyle method' ların eşlenmesini sağlar.
  • @RequestBody body-post' dan gelen json veriyi java nesnesine dönüştürür.
  • @ResponseBody java nesnesini json' a dönüştürür ve response olarak gönderir.
  • Jackson lib. @RequestBody ve @ResponseBody kullanıldığında dönüşüm için devreye girer.
  • Spring 4.x+ ile @RestController kullanabilirsiniz. Bu @RequestMapping ve @ResponseBody birleşimidir.

@Controller
public class CRUDController {
    
    public static final String APP_NAME = "CRUD %100 AJAX";
    
    @Autowired 
    PersonDAOImpl dAOImpl;
    
    @RequestMapping(value = "/" , method = RequestMethod.GET)
    public String index(ModelMap map) {
        map.put("users", dAOImpl.getAllPerson());
        map.put("hello", APP_NAME);
        return "index";
    }
    
    @RequestMapping(value = "/addPerson" , method = RequestMethod.POST)
    @ResponseBody
    public Person addPerson(@RequestBody Person person) {
        if (person.getName().equals("")) {
            return null;
        }
        dAOImpl.insert(person);
        
        return person;
    }

    @RequestMapping(value = "/updatePerson" , method = RequestMethod.PUT)
    @ResponseBody
    public String updatePerson(@RequestBody Person person) {
        dAOImpl.update(person);
        return "{\"status\":\"Success\"}";
    }
    
    @RequestMapping(value = "/deletePerson" , method = RequestMethod.DELETE)
    @ResponseBody
    public void deletePerson(@RequestBody Map<String, String> id) {
        dAOImpl.remove(Integer.parseInt(id.get("id")));
    }
     
}

Adım 6 :

DAO' da Java 8 Streams kullanıyoruz bu yüzden Maven ayarlarında JDK 1.8 olduğuna dikkat edelim.


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerArguments>
            <endorseddirs>${endorsed.dir}</endorseddirs>
        </compilerArguments>
    </configuration>
</plugin>


Adım 7 :

@RequestMapping(value="/") dönen sahte datamızı Jstl->foreach kullanarak table' a bastırıyoruz.

WEB-INF/views/index.jsp

<table id="person-list" class="table table-striped table-hover" style="width: 50%">
    <tr>
    <th>ID</th>
    <th>Name</th>
    <th>Age</th>
    </tr>
    <c:forEach items="${users}" var="user">
        <tr>
            <td> ${user.id}</td>
            <td class="display${user.id}" id="displayName${user.id}"> ${user.name}</td>
            <td class="display${user.id}" id="displayAge${user.id}"> ${user.age}</td>
            <td style="display: none;" class="edit${user.id}"> 
              <input type="text" name="editName${user.id}" id="editName${user.id}" value="${user.name}" />
            </td>
            <td style="display: none;" class="edit${user.id}"> 
              <input type="text" name="editAge${user.id}" id="editAge${user.id}" value="${user.age}" />
            </td>
            <td>
              <input type="button" class="delete-person" data-item-id="${user.id}" id="delete-person${user.id}" value="Delete" /> 
            </td>
            <td> 
              <input type="button" class="update-person" data-item-id="${user.id}" id="update-person${user.id}" value="Update" /> 
            </td>
            <td style="display: none;" class="edit${user.id}">
              <input type="button"  class="update-person" data-item-id="${user.id}" id="edit-person${user.id}" value="Confirm" /> 
            </td>
            <td id="updatecheck${user.id}" style="display: none"><span class="label label-success" >OK</span></td>
        </tr>
    </c:forEach>
    <tr>
        <td>NEW</td>
        <td><input type="text" name="name" id="name" placeholder="Enter Name" /></td>
        <td><input type="text" name="age" id="age" placeholder="Enter Age" /></td>
        <td>
            <input type="button" id="add-person" value="Add" />
        </td>
    </tr>
</table>
<span class="otherchecks label label-success" style="display: none;">SUCCESS</span>


Adım 8 :

jQuery Ajax Post metodu : Post edilecek verileri alıp, Json formatına uygun hale getiriyoruz. @RequestMapping(value="addPerson") metoduna post edilecek şekilde url ve type belirtiyoruz.

  • Server-client uyumu sağlamak için Content-Type:"application/json" tanımlamamız gerekiyor. Çünkü server(@RequestBody) bizden json/xml data bekliyor(Consumes). (varsayılan olarak kullanılan= application/x-www-form-urlencoded). Aksi taktirde 415 Unsupported Media Type hatası döndürebilir server.
  • Server' ın döndürdüğü yanıtı (body-response) jquery success ile yakalayıp işleyeceğiz. Server @ResponseBody ile zaten Json veri döndürecek (Produces). Dönen veriyi nokta notasyonu ile kolaylıkla parse edebilirsiniz.
  • jQuery dönen belirli data formatlarına ayak uydurur. dataType:"json" yazmaya gerek yok.
    default: Intelligent Guess (xml, json, script, or html)
  • success callback fonksiyonuna dönen datayı kullanarak yeni bir table row(tr) oluşturup DOM sayesinde sayfayı yenilemeden tabloya ekliyoruz. Karışık gelebilir, mantığı bildikten sonra client tarafında daha etkili framework' lar kullanabilirsiniz(Angular vb).

$("#add-person").click(function(){

    var name= $("#name").val();
    var age = $("#age").val();

    var data = JSON.stringify({"name":name,"age":age});

    $.ajax({
    type : "POST",
    url : "${pageContext.request.contextPath}/addPerson",
    contentType: "application/json",
    data : data,
    success: function(data){

    if(data===""){
        return;
    }else{           
        var html = [];
        html.push(
          '<tr>',
          '<td>'+data.id+'</td>',
          '<td class="display'+data.id+'" id="displayName'+data.id+'">'+data.name+'</td>',
          '<td class="display'+data.id+'" id="displayAge'+data.id+'">'+ data.age+'</td>',
          '<td style="display: none;" class="edit'+data.id+'"> <input type="text" name="editName'+data.id+'" id="editName'+data.id+'" value="'+data.name+'" /></td>',
          '<td style="display: none;" class="edit'+data.id+'"> <input type="text" name="editAge'+data.id+'" id="editAge'+data.id+'" value="'+data.age+'" /></td>',
          '<td><input type="button" class="delete-person" data-item-id="'+data.id+'" id="delete-person'+data.id+'" value="Delete" /></td>',
          '<td> <input type="button" class="update-person" data-item-id="'+data.id+'" id="update-person'+data.id+'" value="Update" /> </td>',
          '<td style="display: none;" class="edit'+data.id+'"> <input type="button"  class="update-person" data-item-id="'+data.id+'" id="edit-person'+data.id+'" value="Confirm" /> </td>',
          '<td id="updatecheck'+data.id+'" style="display: none;background-color: greenyellow; color:white;">OK</td>',
          '</tr>'
        );
        var a = html.join("");
        $('#person-list tr:last').before(a);

           $("#name").val("");
           $("#age").val("");

           $(".otherchecks").show();
           setTimeout(function() { $(".otherchecks").hide(); }, 2000);
         }
       }
    });
});


Adım 9 :

@RequestMapping(value="/updatePerson") için uygun url ve type belirtiyoruz.

  • Güncelleme işlemi biraz daha fazla kod satırına sahip. Kısacası, tablonun her satırındaki elemanların belirli bir class ve id değerleri var. Update butonuna basıldığında normal text' lerin yerine edit-text ler geçiyor. (display:none özelliğini show() hide() metotlarıyla değiştirerek)
  • Bir element' de data-item-id="${user.id}" şeklinde tanımlanan attribute' a var id = $(event.target).data('itemId'); ile erişilebilir. Böylece, tabloda tıklanan her satıra özgü değerlere erişilebilir. Confirm butonuna basıldığında, bu değerler server' a post ediliyor ve yeni verilerle eski verileri tabloda güncelliyoruz.

  • $("#person-list").on('click','.update-person',function(){
    
        var value = $(event.target).val();
        var id = $(event.target).data('itemId');
        var tdclassshow = ".edit"+id;
        var tdclasshide = ".display"+id;
        var editnameid = "#editName"+id;
        var editageid = "#editAge"+id;
    
        var confirmbuttonshow = ".edit"+id;
    
        if(value==="Update"){
            $(tdclassshow).show();
            $(tdclasshide).hide();
            $(confirmbuttonshow).show();
        }else if(value==="Confirm"){
            var name = $(editnameid).val();
            var age = $(editageid).val();
            var data = JSON.stringify({"id":id ,"name":name,"age":age});
    
            $.ajax({
               type : "PUT",
               url : "${pageContext.request.contextPath}/updatePerson",
               contentType: "application/json",
               data : data,
               success: function(data){
    
                 $(tdclassshow).hide();
                 $(tdclasshide).show();
                 $(confirmbuttonshow).hide();
    
                 var dispName = "#displayName"+id;
                 var dispAge = "#displayAge"+id;
                 $(dispName).text(name);
                 $(dispAge).text(age);
    
                 $('#updatecheck'+id).show();
                 setTimeout(function() { $('#updatecheck'+id).hide(); }, 2000);
    
               }
             });
    
        }
    
    });
    
    

    Adım 10 :

    @RequesMapping(value="/deletePerson") uygun url ve type belirleyelim.

    • Tıklanan "Delete" butonundan data-item-id="${user.id}" person id alıp post ediyoruz. public void deletePerson(@RequestBody Map<String, String> id) metodunda id' yi alıp, eşleşen person' ı siliyoruz.
    • $(rowId).closest('tr').remove(); ile butona en yakın satırı( tr) siliyoruz

    $("#person-list").on('click','.delete-person',function(event){
        var id = $(event.target).data('itemId');
        var data = JSON.stringify({"id":id});
        var rowId= "#"+event.target.id;
        $.ajax({
        type : "DELETE",
        url : "${pageContext.request.contextPath}/deletePerson",
        contentType: "application/json",
        data : data,
        success: function(data){
           $(rowId).closest('tr').remove();
           $(".otherchecks").show();
           setTimeout(function() { $(".otherchecks").hide(); }, 2000);
        }
        });
    });
    
    

    Kaynak Kodlara bakmak için Github Source Code
    Bitir

    Hiç yorum yok:

    Yorum Gönderme