Java Webservice with Retrofit CURD with image uploading using Multipart

Spring and Hibernate based WebService

Project Structure:

AppConfig.java

    
        package com.deepsingh44.config;
        import java.util.Properties;
        import java.util.concurrent.TimeUnit;
        import javax.sql.DataSource;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.ComponentScan;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.context.annotation.PropertySource;
        import org.springframework.core.env.Environment;
        import org.springframework.http.CacheControl;
        import org.springframework.jdbc.datasource.DriverManagerDataSource;
        import org.springframework.orm.hibernate5.HibernateTransactionManager;
        import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
        import org.springframework.transaction.annotation.EnableTransactionManagement;
        import org.springframework.web.multipart.commons.CommonsMultipartResolver;
        import org.springframework.web.servlet.config.annotation.EnableWebMvc;
        import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
        import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
        
        import com.deepsingh44.model.Quotes;
        
        @Configuration
        @EnableWebMvc
        @EnableTransactionManagement
        @ComponentScan(basePackages = { "com.deepsingh44" })
        @PropertySource(value = "classpath:/application.properties")
        public class AppConfig {
        
        @Autowired
        private Environment environment;
        
        @Bean
        public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.class"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.user"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.pass"));
        System.out.println("Deep database " + dataSource);
        return dataSource;
        }
        
        @Bean
        public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        // sessionFactory.setPackagesToScan(new String[] { "com.deepsingh44.model" });
        sessionFactory.setAnnotatedClasses(Quotes.class);
        sessionFactory.setHibernateProperties(hibernateProperties());
        System.out.println("deep session " + sessionFactory);
        return sessionFactory;
        
        }
        
        private Properties hibernateProperties() {
        Properties properties = new Properties();
        // properties.put("hibernate.dialect",
        // environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
        System.out.println(properties);
        return properties;
        
        }
        
        @Bean
        public HibernateTransactionManager getTransactionManager() {
        System.out.println("transaction " + "hello");
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        System.out.println("transaction " + transactionManager);
        return transactionManager;
        }
        
        @Bean
        public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver cm = new CommonsMultipartResolver();
        cm.setMaxUploadSize(10*1024*1024);
        return cm;
        }
        
        }
    

FrontController.java


        package com.deepsingh44.controller;
        import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
        import com.deepsingh44.config.AppConfig;
        public class FrontController extends AbstractAnnotationConfigDispatcherServletInitializer {
        
        @Override
        protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return new Class[] { AppConfig.class };
        }
        
        @Override
        protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return null;
        }
        
        @Override
        protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return new String[] { "/" };
        }
        
        }
    

QuotesCntroller.java

        
package com.deepsingh44.controller;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.deepsingh44.model.Quotes;
import com.deepsingh44.service.QuotesService;

@RestController
public class QuotesController {
	@Autowired
	private QuotesService quotesService;

	@PostMapping("/add")
	public Quotes addQuotes(@RequestBody Quotes quotes) {
		return quotesService.addQuotes(quotes);
	}

	@GetMapping("/quotes")
	public List<Quotes> getAllQuotes() {
		return quotesService.getAllQuotes();
	}

	@DeleteMapping("/quotes/{id}")
	public Quotes deletQuotes(@PathVariable() int id) {
		return quotesService.deleteQuotes(id);
	}

	@PutMapping("/update/{id}")
	public Quotes updateQuotes(@PathVariable int id, @RequestBody() Quotes quotes) {
		return quotesService.updateQuotes(id, quotes);
	}

	@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	public String uploadFile(@RequestBody MultipartFile file, HttpServletRequest req) throws IOException {
		String result = "Not Success";
		String root = req.getServletContext().getRealPath("/");
		File folder = new File(root, "images");
		if (!folder.exists())
			folder.mkdir();
		File myfile = File.createTempFile("image", ".jpg", folder);
		file.transferTo(myfile);
		System.out.println(myfile.getAbsolutePath());
		result = "Successfully Uploaded";
		return result;
	}

}
        
    

Quotes.java

        
            package com.deepsingh44.model;
            
            import javax.persistence.Entity;
            import javax.persistence.GeneratedValue;
            import javax.persistence.GenerationType;
            import javax.persistence.Id;
            import javax.persistence.Table;
            
            @Entity
            public class Quotes {
            @Id
            @GeneratedValue(strategy = GenerationType.AUTO)
            private int id;
            private String title;
            private String description;
            
            public int getId() {
            return id;
            }
            
            public void setId(int id) {
            this.id = id;
            }
            
            public String getTitle() {
            return title;
            }
            
            public void setTitle(String title) {
            this.title = title;
            }
            
            public String getDescription() {
            return description;
            }
            
            public void setDescription(String description) {
            this.description = description;
            }
            
            }

        
    

QuotesRepo.java

        
package com.deepsingh44.repo;

import java.io.Serializable;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.deepsingh44.model.Quotes;

@Repository
public class QuotesRepo {
	@Autowired
	private SessionFactory sessionFactory;

	public Serializable addQuotes(Quotes quotes) {
		return sessionFactory.getCurrentSession().save(quotes);
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	public List<Quotes> getAllQuotes() {
		return sessionFactory.getCurrentSession().createCriteria(Quotes.class).list();
	}

	public Quotes deleteQuotes(int id) {
		Quotes quotes = getQuotesById(id);
		sessionFactory.getCurrentSession().delete(quotes);
		return quotes;
	}

	public Quotes getQuotesById(int id) {
		return sessionFactory.getCurrentSession().get(Quotes.class, id);
	}

	public Quotes updateQuotes(int id,Quotes quotes) {
		Quotes databasequotes = getQuotesById(id);
		if (databasequotes != null) {
			databasequotes.setTitle(quotes.getTitle());
			databasequotes.setDescription(quotes.getDescription());
			sessionFactory.getCurrentSession().update(databasequotes);
			return databasequotes;
		} else {
			return new Quotes();
		}
	}

}
        
    

QuotesService.java

        
package com.deepsingh44.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.deepsingh44.model.Quotes;
import com.deepsingh44.repo.QuotesRepo;

@Service
public class QuotesService {
	@Autowired
	private QuotesRepo quotesRepo;

	@Transactional
	public Quotes addQuotes(Quotes quotes) {
		return ((Integer) (quotesRepo.addQuotes(quotes)) > 0) ? quotes : new Quotes();
	}

	@Transactional
	public List<Quotes> getAllQuotes() {
		return quotesRepo.getAllQuotes();
	}

	@Transactional
	public Quotes deleteQuotes(int id) {
		return quotesRepo.deleteQuotes(id);
	}

	@Transactional
	public Quotes updateQuotes(int id,Quotes quotes) {
		return quotesRepo.updateQuotes(id,quotes);
	}

}
        
    

application.properties

        
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.class=com.mysql.jdbc.Driver
jdbc.pass=root
jdbc.user=root

 
hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql = true
hibernate.format_sql = true
hibernate.hbm2ddl.auto = update
        
    

pom.xml

        
    <project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Hello-Spring-Mvc</groupId>
	<artifactId>Hello-Spring-Mvc</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<release>16</release>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.2.3</version>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.3.9</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>5.3.9</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.5.4.Final</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.47</version>
		</dependency>

		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.4</version>
		</dependency>

		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.6</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.3</version>
		</dependency>
	</dependencies>
</project>
        
    

Android Code Here

Project Structure:

Quotes.java

    
package com.example.restapiconsume.model;

public class Quotes {
    private int id;
    private String image;
    private String title;
    private String description;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
    

QuotesService.java

    
package com.example.restapiconsume.service;

import com.example.restapiconsume.model.Quotes;
import java.util.List;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Part;
import retrofit2.http.Path;

public interface QuotesService {

    @GET("quotes/")
    Call<List<Quotes>> getQuotes();

    @POST("add/")
    Call<Quotes> addQuotes(@Body Quotes quotes);

    @PUT("update/{id}")
    Call<Quotes> updateQuotes(@Path("id") int id, @Body Quotes quotes);

    @DELETE("quotes/{id}")
    Call<Quotes> deleteQuotes(@Path("id") int id);

    @Multipart
    @POST("upload/")
    Call<String> uploadFile(@Part MultipartBody.Part file, @Part("file") RequestBody name);
}

    

MainActivity.java

    
package com.example.restapiconsume;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.JsonReader;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;

import com.example.restapiconsume.model.Quotes;
import com.example.restapiconsume.service.QuotesService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {
    private EditText ttile, tdescription, tid;
    private QuotesService quotesService;
    private ImageView imageView, imagepicker;
    private MultipartBody.Part body;
    private RequestBody descBody;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SingleTask singleTask = (SingleTask) getApplication();
        quotesService = singleTask.getRetrofit().create(QuotesService.class);

        tid = findViewById(R.id.id);
        ttile = findViewById(R.id.title);
        tdescription = findViewById(R.id.description);
        imageView = findViewById(R.id.mainimage);
        imagepicker = findViewById(R.id.imagepicker);
        imagepicker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Select image to upload "), 1001);
            }
        });

    }

    private String getRealPathFromURI(Uri contentUri) {
        String[] proj = {MediaStore.Images.Media.DATA};
        CursorLoader loader = new CursorLoader(this, contentUri, proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String result = cursor.getString(column_index);
        cursor.close();
        return result;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1001) {
            if (resultCode == RESULT_OK) {
                Uri selectedImage = data.getData();
                Bitmap bitmap = null;
                try {
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
                    imageView.setImageBitmap(bitmap);
                    String actualpath = getRealPathFromURI(selectedImage);

                    File file = new File(getRealPathFromURI(selectedImage));

                    RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                    body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
                    descBody = RequestBody.create(MediaType.parse("application/json"), "this is image");

                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }
    }

    public void addQuotes(View view) {
        Quotes quotes = new Quotes();
        quotes.setId(Integer.parseInt(tid.getText().toString()));
        quotes.setTitle(ttile.getText().toString());
        quotes.setDescription(tdescription.getText().toString());

        quotesService.addQuotes(quotes).enqueue(new Callback<Quotes>() {
            @Override
            public void onResponse(Call<Quotes> call, Response<Quotes> response) {
                Log.e("error", response.body().toString());
            }

            @Override
            public void onFailure(Call<Quotes> call, Throwable t) {
                Log.e("error", t.toString());
            }
        });

    }

    public void deleteQuotes(View view) {
        int id = Integer.parseInt(tid.getText().toString());
        quotesService.deleteQuotes(id).enqueue(new Callback<Quotes>() {
            @Override
            public void onResponse(Call<Quotes> call, Response<Quotes> response) {
                Log.e("error", response.body().toString());
            }

            @Override
            public void onFailure(Call<Quotes> call, Throwable t) {
                Log.e("error", t.toString());
            }
        });
    }

    public void updateQuotes(View view) {
        int id = Integer.parseInt(tid.getText().toString());
        Quotes quotes = new Quotes();
        quotes.setTitle(ttile.getText().toString());
        quotes.setDescription(tdescription.getText().toString());
        quotesService.updateQuotes(id, quotes).enqueue(new Callback<Quotes>() {
            @Override
            public void onResponse(Call<Quotes> call, Response<Quotes> response) {
                Log.e("error", response.body().toString());
            }

            @Override
            public void onFailure(Call<Quotes> call, Throwable t) {
                Log.e("error", t.toString());
            }
        });
    }

    public void allQuotes(View view) {
        quotesService.getQuotes().enqueue(new Callback<List<Quotes>>() {
            @Override
            public void onResponse(Call<List<Quotes>> call, Response<List<Quotes>> response) {
                Log.e("error", response.body().toString());
            }

            @Override
            public void onFailure(Call<List<Quotes>> call, Throwable t) {
                Log.e("error", t.toString());
            }
        });
    }

    public void uploadImage(View view) {
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(SingleTask.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
        QuotesService quotesService = retrofit.create(QuotesService.class);
        quotesService.uploadFile(body, descBody).enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {

                Log.e("error", new Gson().toJson(response.body()));
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Log.e("error", t.toString());
            }
        });
    }
}
    

SingleTask.java

    
package com.example.restapiconsume;

import android.app.Application;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class SingleTask extends Application {

    private static Retrofit retrofit;
    public static final String BASE_URL = "http://192.168.1.26:9876/Hello-Spring-Mvc/";

    @Override
    public void onCreate() {
        super.onCreate();
        if (retrofit == null) {
            retrofit = new retrofit2.Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }

    }

    public Retrofit getRetrofit() {
        return retrofit;
    }
}
    

activity_main.xml

    
        <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:id="@+id/mainimage"
            android:scaleType="centerCrop"
            android:src="@drawable/gallery" />

        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_gravity="bottom|right"
            android:src="@drawable/gallery"
            android:id="@+id/imagepicker"/>
    </FrameLayout>

    <EditText
        android:id="@+id/id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Id"
        android:padding="20dp" />

    <EditText
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Title"
        android:padding="20dp" />

    <EditText
        android:id="@+id/description"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Description"
        android:padding="20dp" />


    <Button
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="addQuotes"
        android:text="Add Quotes" />

    <Button
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="allQuotes"
        android:text="All Quotes" />

    <Button
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="deleteQuotes"
        android:text="Delete Quotes" />

    <Button
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="updateQuotes"
        android:text="Update Quotes" />

    <Button
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="uploadImage"
        android:text="Upload Image" />
</LinearLayout>
    

GradleScripe/build.gradle(Module)


    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.google.code.gson:gson:2.8.7'
    

Add Below Permission:

        
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE" />
        
    

Output Screen:

No comments: