VueJS + Spring Boot + MongoDB

Merhabalar,
Bugün bir önceki yazıda VueJS tasarladığımız form üzerinden veritabanına kayıt atacağız.

Önceki yazıda uygulamanın Github linkini paylaşmıştım. Link üzerinden kendi lokalinize pull aldıktan sonra aşağıdaki şekilde değişiklik yapmamız gerekmekte;

SignUpForm.vue dosyası içerisinde öncesinde alert gösterdiğimiz kısım aşağıdaki şekilde değişecek;

/*Script kısmının başında api-service dosyasını import etmemiz gerekli.*/
import {post} from '../common/api-service'

...

if(this.form.password === this.form.passwordCheck){
          post('/api/signup/', this.form).then(response => {
            if(response.data.status){
              this.$bvModal.msgBoxOk("Kayıt başarıyla eklendi!", {
                title: 'Başarılı',
                size: 'sm',
                buttonSize: 'sm',
                okVariant: 'success',
                headerClass: 'p-2 border-bottom-0',
                footerClass: 'p-2 border-top-0',
                centered: true
              })
            }
            else{console.log(response)}
          })
        }

Aynı zamanda src altında common adında yeni bir klasör oluşturup altında iki adet js dosyası (api-service.js ve config.js) oluşturmamız gerekmekte;

api-service.js dosyasının içeriği aşağıdaki gibidir;

import axios from 'axios'
import {BASE_URL} from '../common/config.js'

export async function post (path = '', params){
    try {
        console.log("params = " + params);
        return axios.post(BASE_URL + path, params);
    } catch (err) {
        console.log(err);
        throw new Error('Http post error on api-service.js');
    }
}

config.js dosyası ise aşağıdaki gibidir;

export const BASE_URL = 'http://localhost:8081/'

Son olarak main.js dosyası içerisinde ModalPlugin import etmeliyiz.

import { ModalPlugin } from 'bootstrap-vue'
Vue.use(ModalPlugin)

Bu değişiklikleri yaptıktan sonra yeni bir spring projesi oluşturalım. Bunun için start.spring.io kullanabilirsiniz.

Bağımlılıklar aşağıdaki gibi olabilir;

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>
		<dependency>
			<groupId>io.projectreactor</groupId>
			<artifactId>reactor-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

Tüm proje bittiğinde yapı aşağıdaki gibi olacaktır;

Proje Structure

Öncelikle User ve UserDTO ile başlayalım. Bunlar bizim önyüzden gelen veriyi tutan ve veritabanına kayıt atarken kullandığımız objeler olacak.

*DTO = Data Transfer Object

User classı aşağıdaki gibidir;

**Anotasyonlar lombok sayesinde kullanılmakta.

@Data
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
@Document(collection = "user")
public class User {
    @Id
    private String id;
    private String email;
    private String name;
    private String password;
    @Builder.Default
    private boolean status = true;
}

UserDTO ise aşağıdaki gibidir;

@Data
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
    private String id;
    private String email;
    private String name;
    private String password;
    private String passwordCheck;
    @Builder.Default
    private boolean status = true;
    private String message;
    private int code;
}

UserDTO objesi User objesine baktığımızda belli olacağı gibi Rest yapılarda iletişimde kullanılmak üzere oluşturduğumuz objedir. Veritabanındaki her bilgiyi paylaşmak istemiyorsak bu şekilde DTO objesi oluşturup istediğimiz alanları istediğimiz şekilde gönderebiliriz.

Repository interface aşağıdaki gibidir;


@Repository
public interface SignUpRepository extends ReactiveMongoRepository<User, String>{
}

Bu repository’yi kullanacak service interfacemiz (SignUpService) ve service (ISignUpService) classımız var.Bunlarda aşağıdaki şekilde;

public interface SignUpService {
    User save(UserDTO user);
}

****************************************
@Service
public class ISignUpService implements SignUpService{

    @Autowired
    private SignUpRepository signUpRepository;

    @Override
    public User save(UserDTO user) {
        return signUpRepository.save(dtoToMap(user)).block();
    }

    private User dtoToMap(UserDTO dto){
        return User.builder()
                .email(dto.getEmail())
                .name(dto.getName())
                .password(dto.getPassword())
                .status(dto.isStatus())
                .build();
    }
}

Şimdi bu servisi çağıracak controller classımıza gelelim.

//Farklı bir domainden gelen isteklere izin vermek için ekliyoruz
@CrossOrigin("*")
@RestController
@RequestMapping("/api")
public class SignUpController {

    @Autowired
    private ISignUpService signUpService;
    @Autowired
    private SignUpManager manager;

    @PostMapping(path = "/signup/")
    public UserDTO save(@RequestBody UserDTO user){
        try{
            int valid = manager.validate(user);
            if (valid == 202){
                User savedUser = signUpService.save(user);
                UserDTO userDTO = mapToDTO(savedUser, HttpStatus.ACCEPTED.value(), "Ok!");
                return userDTO;
            }
            else{
                return mapToDTO(User.builder().status(false).build(), HttpStatus.BAD_REQUEST.value(), "Hata!");
            }
        }catch (Exception e){
            return mapToDTO(User.builder().status(false).build(), HttpStatus.BAD_GATEWAY.value(), "Hata!");
        }
    }

    private UserDTO mapToDTO(User user, int code, String message){
        return UserDTO.builder().id(user.getId())
                                .name(user.getName())
                                .password(user.getPassword())
                                .passwordCheck(user.getPassword())
                                .email(user.getEmail())
                                .status(user.isStatus())
                                .message(message)
                                .code(code)
                                .build();
    }

Manager kısmında ise aşağıdaki şekilde basit kontrolleri yapıyoruz;

Bu kontrolleri aslında önyüzde de yapıyoruz fakat rest api mantığında backendin de kontrol mekanizması olması daha doğru olacaktır.

@Service
public class SignUpManager {

    public int validate(UserDTO userDTO){
        try{
            if(userDTO.getName().isEmpty()){
                return HttpStatus.BAD_REQUEST.value();
            }
            if(userDTO.getEmail().isEmpty()){
                return HttpStatus.BAD_REQUEST.value();
            }
            if(userDTO.getPassword().isEmpty()){
                return HttpStatus.BAD_REQUEST.value();
            }
            if(userDTO.getPasswordCheck().isEmpty()){
                return HttpStatus.BAD_REQUEST.value();
            }
            if(!userDTO.getPassword().equals(userDTO.getPasswordCheck())){
                return HttpStatus.BAD_REQUEST.value();
            }
            return HttpStatus.ACCEPTED.value();
        }
        catch (Exception e){
            return HttpStatus.BAD_REQUEST.value();
        }
    }
}
application.properties kısmında mongodb için gerekli bilgileri yazıyoruz;
server.port = 8081//rest apimizin çalışacağı port
//mongo bilgileri
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.auto-index-creation=true
spring.data.mongodb.database=Users
spring.data.mongodb.username=root
spring.data.mongodb.password=example

Son olarak docker ile mongo db ayağa kaldıracağız;

Docker-compose.yml dosyası içeriği aşağıdaki gibi olmalı;

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

Docker dosyasını ayağa kaldırmak içinse bulunduğu konuma gidip, aşağıdaki komutu çalıştırabilirsiniz;

docker-compose -f docker-compose.yml up

Her şey doğru çalışıyorsa uygulamamızı deneyebiliriz;

Veritabanından kontrol etmemiz gerekirse;

Peki bu istek sonucunda rest servisimiz bize nasıl bir response dönmekte?

Bu şekilde frontend tarafında status bilgisini veya code bilgisini kontrol ederek ekrana valid bir hata dönebiliriz. DTO objeleri kullanmak bu yüzden önemlidir.

Umarım bir şeyler için yardımcı olmuşumdur.

Github Linki

Android – QRCodeReader (Zxing)

Merhaba arkadaşlar bu yazımızda Zxing kütüphanesi kullanılarak basit bir QR Kod okuyucusu yapacağız.

asdasd

Ekran görüntüsü yukarıda ki gibi olacak. Kodlara geçmeden, build.gradle dosyasına bir kaç ekleme yapmamız gerecek. Dependencies kısmına

compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
compile 'com.google.zxing:core:3.2.1'

şeklinde gerekli kütüphaneyi ekliyoruz.

Daha sonra manifests dosyasına izinimizi ekliyoruz;

<uses-permission android:name="android.permission.CAMERA"/>

Şimdi kodlara geçersek;

private Button button;
private TextView text_qr_code_sonuc,txt_sonuc,txt_code_kind,txt_qr_code_kind_result;

ilk kısımda tasarımda eklediklerimizi kodda tanımlıyoruz. Daha sonra ;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final Activity activity = this;
    button = (Button) findViewById(R.id.button);
    txt_sonuc = (TextView) findViewById(R.id.txt_sonuc);
    text_qr_code_sonuc = (TextView) findViewById(R.id.qr_code_sonucu);
    txt_code_kind = (TextView) findViewById(R.id.txt_code_kind);
    txt_qr_code_kind_result = (TextView) findViewById(R.id.txt_qr_code_kind_result);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Bu activity içinde çalıştırıyoruz.
            IntentIntegrator integrator = new IntentIntegrator(activity);
            //Kütüphanede bir kaç kod tipi var biz hepsini tarayacak şekilde çalıştırdık.
            //integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
            //şeklindede sadece qr code taratabilirsiniz.
            integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES);
            //Kamera açıldığında aşağıda yazı gösterecek
            integrator.setPrompt("Scan");
            //telefonun kendi kamerasını kullandırıcaz
            integrator.setCameraId(0);
            //okuduğunda 'beep' sesi çıkarır
            integrator.setBeepEnabled(true);
            //okunan barkodun image dosyasını kaydediyor
            integrator.setBarcodeImageEnabled(false);
            //scan başlatılıyor
            integrator.initiateScan();
        }
    });
}

Bu kısıma kadar yaptıklarımız bize kamerayı açtırıp kodu taratmamıza yarayacak fakat dönen cevabı değerlendirmemiz gerekli. Bunun içinde onCreate metodunun bitimine aşağıdaki kısmı yazıyoruz;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //Kütüphane okuduktan sonra bu metodla bize result döndürüyor.
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if(result != null) {
        if(result.getContents() == null) {
            text_qr_code_sonuc.setText("Kod Sonucu:");
            txt_sonuc.setText("Qr Code Bulunamadı.");
            txt_code_kind.setText("Kod Türü:");
            txt_qr_code_kind_result.setText("Bulunamadı.");
        } else {
            Log.d("MainActivity", "Scanned");
            text_qr_code_sonuc.setText("Kod Sonucu:");
            txt_sonuc.setText(result.getContents());
            txt_code_kind.setText("Kod Türü:");
            txt_qr_code_kind_result.setText(result.getFormatName());
        }
    }
}

 

Sonucu değerlendirmek size kalmış. Ben basit şekilde yapılacakları göstermeye çalıştım. Umarım beğenirsiniz. Uygulamayı buradan indirebilirsiniz.