Search code examples
mysqlmavenservletsjakarta-eethymeleaf

The path to a database with jee maven project


I'm currently making a website with Java EE, using maven, thymeleaf, and hosting it on heroku (database addon is JawsDBMySQL). I've created a simple html page in order to check the good working of it. Of course it works perfectly for a local upload : the file goes to a folder I've designed.

In my data base the path to my local storage is stored as a string. I've also add a longblob column, but I did not really understood how to use it.

Now I want to store files into my database when my application is online.

I didn't found solution that perfectly match with my issue, but I'm quite sure it is pretty simple.

Hoping I have been clear enough,

thanks for your help.

Servlet that display a page on /home2 with the list of the pictures

package marquise.servlets;


import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;

import marquise.services.InformationLibrary;



@WebServlet("/home2")
public class HomeServlet extends AbstractGenericServlet2 {

    private static final long serialVersionUID = 5402133218271984030L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        TemplateEngine templateEngine = this.createTemplateEngine(req);

        WebContext context = new WebContext(req, resp, getServletContext());
        //Country countryFilter = (Country) req.getSession().getAttribute("countryFilter");

        context.setVariable("images", InformationLibrary.getInstance().listAllImages());
        //context.setVariable("cities", CityService.getInstance().listAllCities(countryFilter));
        //context.setVariable("countries", Country.values());

        //context.setVariable("countryFilterSelected", countryFilter);

        templateEngine.process("home", context, resp.getWriter());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String countryString = req.getParameter("countryFilter");



        resp.sendRedirect("home2");

    }



}

Servlet for the path

@WebServlet("/imagepicture")
public class CityPictureServlet extends AbstractGenericServlet2 {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer imageId = Integer.parseInt(req.getParameter("id"));
        Path picturePath = InformationLibrary.getInstance().getPicturePatch(imageId);

        Files.copy(picturePath, resp.getOutputStream());
    }


}

servlet that print image details (not important right now) package marquise.servlets;

@WebServlet("/detail")
public class CityDetailServlet extends AbstractGenericServlet2 {

    private static final long serialVersionUID = 8559083626521311046L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        TemplateEngine templateEngine = this.createTemplateEngine(req);

        WebContext context = new WebContext(req, resp, getServletContext());

        Integer idImage = Integer.parseInt(req.getParameter("id"));
        context.setVariable("image", InformationLibrary.getInstance().getImage(idImage));       
        //context.setVariable("comments", InformationLibrary.getInstance().listCommentsByCity(idCity));
        context.setVariable("comments", InformationLibrary.getInstance().listAllImages());



        templateEngine.process("imagedetail", context, resp.getWriter());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

            Integer cityId = Integer.parseInt(req.getParameter("id"));



            resp.sendRedirect(String.format("detail?id=%d", cityId));

            resp.sendRedirect("home2");
        }
}

HTML page displaying the list of my images

    <!doctype html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="utf-8">
    <title>City Explorer</title>
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css">
    <link rel="stylesheet" href="fontawesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="css/custom.css">

    </head>
    <body>
        <header th:replace="~{common::header}"></header>

        <div id="mainContent" class="container-fluid">
            <section class="cityfilters">
                <h3>Filters</h3>
                <form class="form-inline" method="post">
                    <div class="form-group">
                        <label for="countryInput">Country</label>
                        <select class="form-control" id="countryInput" name="countryFilter">
                            <option value="">All countries</option>
                            <option th:each="country : ${countries}" th:value="${country}" th:selected="${countryFilterSelected} == ${country}">[[${country.label}]]</option>
                        </select>
                    </div>
                    <input type="submit" class="btn btn-default" value="Filter">
                </form>
            </section>
            <section class="citylist">
                <article class="citybox" th:each="image : ${images}">
                    <h3>
                        [[${image.name}]] 
                        <a th:href="'deleteimage?id='+${image.id}" class="btn btn-xs btn-danger pull-right"> 
                            <i class="fa fa-times" aria-hidden="true"></i>
                        </a>
                    </h3>
                    <p th:text="${image.summary}" class="summary"></p>
                    <div class="btn-toolbar actionbar" role="toolbar">
                        <div class="btn-group" role="group">
                            <a th:href="'detail?id='+${image.id}" class="btn btn-primary"><i
                                class="fa fa-eye" aria-hidden="true"></i> See details</a>
                        </div>

                    </div>
                    <aside class="cityPhoto">
                        <img th:src="'imagepicture?id='+${image.id}" th:alt="'Vignette '+${image.name}">
                    </aside>
                </article>
            </section>
        </div>
    </body>
    </html>

My Library Class with the path to my computer

public class InformationLibrary {


    private static class InformationLibraryHolder{
        private final static InformationLibrary instance = new InformationLibrary();

    }

    public static InformationLibrary getInstance(){
        return InformationLibraryHolder.instance;
    }

    private InformationDao informationDao = new InformationDaoImpl();
    private UtilisateurDao utilisateurDao = new UtilisateurDaoImpl();
    private CommentaireDao commentaireDao = new CommentaireDaoImpl();
    private ArticleDao articleDao = new ArticleDaoImpl();
    private IdentifiantDao identifiantDao = new IdentifiantDaoImpl();
    private ImageDao imageDao = new ImageDao();


    private static final String PICTURE_MAIN_DIRECTORY = "/Users/louiscauvray/git/projet/src/main/resources";


    private ElementsSiteDao elementsSiteDao = new ElementsSiteDao();

    private InformationLibrary() {
    }


        //Recuperer les informations sur les utilisateurs

    public List<Information> listFilms() {
        return informationDao.listInformations();
    }

    public Information getInformation(Integer id) {
        return informationDao.getInformation(id);
    }

    public Information addInformation(Information information) {
        return informationDao.addInformation(information);
    }

    public List<Utilisateur> listUtilisateurs() {
        return utilisateurDao.listUtilisateurs();
    }

    public Utilisateur getUtilisateur(Integer id) {
        return utilisateurDao.getUtilisateur(id);
    }
    public Utilisateur getUtilisateurByNom(String nom){
        return utilisateurDao.getUtilisateurByNom(nom);
    }

    public Utilisateur addUtilisateur(String nom, String prenom) {
        return utilisateurDao.addUtilisateur(nom, prenom);
    }
        //Gerer les commentaires visible en backoffice

    public List<Commentaire> listCommentaires(){
        return commentaireDao.listCommentaires();
    }

    public Commentaire addCommentaire(String email ,String commentaire){
        return commentaireDao.addCommentaire(email, commentaire);
    }

    public List<Article> listArticles(){
        return articleDao.listArticles();

    }

    public Article addArticle(String title, String texte, LocalDate datePublication, String auteur) {
        return articleDao.addArticle(title, texte, datePublication, auteur);
    }

    public Identifiant getIdentifiant(String login, String motDePasse){
        return identifiantDao.getIdentifiant(login, motDePasse);

    }

    //Methode pour appeler les image et les chemins des images

    public List<Image> listAllImages() {

            return imageDao.listImages();
    }

    public Image getImage(Integer id) {
        if(id == null) {
            throw new IllegalArgumentException("Image id must be provided.");
        }
        return imageDao.getImage(id);
    }

    public void addImage(Image newImage, Part picture) throws IOException {
        if(newImage == null){
            throw new IllegalArgumentException("An image must be provided.");
        }
        if(newImage.getName() == null || "".equals(newImage.getName())) {
            throw new IllegalArgumentException("An image must have a name.");
        }
        if(newImage.getSummary() == null || "".equals(newImage.getSummary())) {
            throw new IllegalArgumentException("An image must have a summary.");
        }
        if(picture == null){
            throw new IllegalArgumentException("An image must contain a picture.");
        }

        Path picturePath = Paths.get(PICTURE_MAIN_DIRECTORY, picture.getSubmittedFileName());

        imageDao.addImage(newImage, picturePath.toString());


        Files.copy(picture.getInputStream(), picturePath);


    }

    public Path getPicturePatch(Integer imageId) {
        String picturePathString = imageDao.getPicturePath(imageId);
        if(picturePathString == null) {
            return getDefaultPicturePath();
        } else {
            Path picturePath = Paths.get(imageDao.getPicturePath(imageId));
            if(Files.exists(picturePath)) {
                return picturePath;
            } else {
                return getDefaultPicturePath();
            }
        }

    }

    private Path getDefaultPicturePath() {
        try {
            return Paths.get(this.getClass().getClassLoader().getResource("city-no-photo.png").toURI());
        } catch (URISyntaxException e) {
            return null;
        }
    }

    // ElementsSite Dao
        public void modifierElementTexte(String idElement, String contenuElement) {
            elementsSiteDao.modifierElementTexte(idElement, contenuElement);
        }

        public void modifierElementImage(String idElement, String contenuElement, String cheminElement) {
            elementsSiteDao.modifierElementImage(idElement, contenuElement, cheminElement);
        }

        public ElementsSite getElementById(String id) {
            return elementsSiteDao.getElementById(id) ;
        }
}

My Dao Class where methods to display images are defined

import marquise.daos.impl.DataSourceProvider;
import marquise.exceptions.CityExplorerRuntimeException;
import marquise.projos.Image;

public class ImageDao {

    public List<Image> listImages() {
        List<Image> images = new ArrayList<Image>();

        try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                Statement statement = connection.createStatement();
                ResultSet resultSet = statement.executeQuery("SELECT * FROM image ORDER BY name")) {
            while (resultSet.next()) {

                images.add(
                        new Image(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getString("summary")));
            }
        } catch (SQLException e) {
            throw new CityExplorerRuntimeException("Error when getting images", e);
        }

        return images;
    }

    public Image getImage(Integer id) {
        try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                PreparedStatement statement = connection.prepareStatement("SELECT * FROM image WHERE id = ?")) {
            statement.setInt(1, id);
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {

                    return new Image(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getString("summary"));
                }
            }
        } catch (SQLException e) {
            throw new CityExplorerRuntimeException("Error when getting images", e);
        }
        return null;
    }

    public void addImage(Image newImage, String picturePath) {
        try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                PreparedStatement statement = connection.prepareStatement("INSERT INTO image(name, summary, picture) VALUES (?, ?, ?)")) {
            statement.setString(1, newImage.getName());
            statement.setString(2, newImage.getSummary());
            statement.setString(3, picturePath);
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new CityExplorerRuntimeException("Error when getting images", e);
        }
    }
    public String getPicturePath(Integer id) {
        try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                PreparedStatement statement = connection.prepareStatement("SELECT picture FROM image WHERE id = ?")) {
            statement.setInt(1, id);
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    return resultSet.getString("picture");
                }
            }
        } catch (SQLException e) {
            throw new CityExplorerRuntimeException("Error when getting images", e);
        }
        return null;
    }

}

Solution

  • Finally I found a solution to my problem :

    I added a longblob column into my data base table, and changed a bit my method.

    Here is my final code if you need it :

    The DaoClass :

    package marquise.daos;
    
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    
    
    
    
    import marquise.daos.impl.DataSourceProvider;
    import marquise.exceptions.CityExplorerRuntimeException;
    import marquise.projos.Image;
    
    public class ImageDao {
    
        public List<Image> listImages() {
            List<Image> images = new ArrayList<Image>();
    
            try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    Statement statement = connection.createStatement();
                    ResultSet resultSet = statement.executeQuery("SELECT * FROM image ORDER BY name")) {
                while (resultSet.next()) {
    
                    images.add(
                            new Image(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getString("summary")));
                }
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
    
            return images;
        }
    
        public Image getImage(Integer id) {
            try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    PreparedStatement statement = connection.prepareStatement("SELECT * FROM image WHERE id = ?")) {
                statement.setInt(1, id);
                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
    
                        return new Image(resultSet.getInt("id"), resultSet.getString("name"), resultSet.getString("summary"));
                    }
                }
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
            return null;
        }
    
        public void addImage(Image newImage, String picturePath) {
            try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    PreparedStatement statement = connection.prepareStatement("INSERT INTO image(name, summary, picture) VALUES (?, ?, ?)")) {
                statement.setString(1, newImage.getName());
                statement.setString(2, newImage.getSummary());
                statement.setString(3, picturePath);
                statement.executeUpdate();
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
        }
    
        public void addImage(Image img, InputStream is){
            try(Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    PreparedStatement statement = connection.prepareStatement("INSERT INTO image(name, summary, image) VALUES (?, ?, ?)")) {
                statement.setString(1, img.getName());
                statement.setString(2, img.getSummary());
                statement.setBinaryStream(3, is);   
                statement.executeUpdate();
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
        }
        public String getPicturePath(Integer id) {
            try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    PreparedStatement statement = connection.prepareStatement("SELECT picture FROM image WHERE id = ?")) {
                statement.setInt(1, id);
                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        return resultSet.getString("picture");
                    }
                }
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
            return null;
        }  
        public InputStream getPicture(Integer id) {
            try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    PreparedStatement statement = connection.prepareStatement("SELECT image FROM image WHERE id = ?")) {
                statement.setInt(1, id);
                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        return resultSet.getBinaryStream("image");
                    }
                }
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
            return null;
        }
        /*public InputStream getPicture(Integer id) {
            try (Connection connection = DataSourceProvider.getInstance().getDataSource().getConnection();
                    PreparedStatement statement = connection.prepareStatement("SELECT image FROM image WHERE id = ?")) {
                statement.setInt(1, id);
                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        return resultSet.getBlob("image") == null ? null : resultSet.getBlob("image").getBinaryStream();
                    }
                }
            } catch (SQLException e) {
                throw new CityExplorerRuntimeException("Error when getting images", e);
            }
            return null;
        }*/
    
    
    
    }
    

    the addimage servlet :

    package marquise.servlets;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.WebContext;
    
    import marquise.projos.Image;
    import marquise.services.InformationLibrary;
    
    @WebServlet("/addimage")
    @MultipartConfig
    public class ImageAddServlet extends AbstractGenericServlet2 {
    
        private static final long serialVersionUID = -3497793006266174453L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("UTF-8");
            TemplateEngine templateEngine = this.createTemplateEngine(req);
    
            WebContext context = new WebContext(req, resp, getServletContext());
            if(req.getSession().getAttribute("imageCreationError") != null) {
                context.setVariable("errorMessage", req.getSession().getAttribute("imageCreationError"));
                context.setVariable("image", (Image) req.getSession().getAttribute("imageCreationData"));
    
                req.getSession().removeAttribute("imageCreationError");
                req.getSession().removeAttribute("imageCreationData");
            } else {
                context.setVariable("image", new Image(null, null, null));
            }
            context.setVariable("countries", context);
            templateEngine.process("connectedUsers/imageadd", context, resp.getWriter());
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String name = req.getParameter("name");
            String summary = req.getParameter("summary");
    
    
    
            Part imagePicture = req.getPart("picture");
            Image newImage = new Image(null, name, summary);
            InputStream is  = imagePicture.getInputStream();
    
            try {
                InformationLibrary.getInstance().addImage(newImage, is);
                resp.sendRedirect("certificatsAdmin");
            } catch (IllegalArgumentException|IOException e) {
                req.getSession().setAttribute("imageCreationError", e.getMessage());
                req.getSession().setAttribute("imageCreationData", newImage);
                resp.sendRedirect("addimage");
            } 
    
        }
    
    
    }
    

    The listImage servlet :

    package marquise.servlets;
    
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.WebContext;
    
    import marquise.services.InformationLibrary;
    
    
    
    @WebServlet("/certificatsAdmin")
    public class listeCertifServlet extends AbstractGenericServlet2 {
    
        private static final long serialVersionUID = 5402133218271984030L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("UTF-8");
            PrintWriter out = resp.getWriter();
            HttpSession session=req.getSession(false);
    
            if(session != null){}
            else{
                resp.sendRedirect("connexion");
                out.println("Veuillez entre un mot de passe correct");
            }
            TemplateEngine templateEngine = this.createTemplateEngine(req);
    
            WebContext context = new WebContext(req, resp, getServletContext());
            //Country countryFilter = (Country) req.getSession().getAttribute("countryFilter");
    
            context.setVariable("images", InformationLibrary.getInstance().listAllImages());
            //context.setVariable("cities", CityService.getInstance().listAllCities(countryFilter));
            //context.setVariable("countries", Country.values());
    
            //context.setVariable("countryFilterSelected", countryFilter);
    
            templateEngine.process("admin/certificatsAdmin", context, resp.getWriter());
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String countryString = req.getParameter("countryFilter");
    
    
    
            resp.sendRedirect("certificatsAdmin");
    
        }
    
    
    
    }