1

I have a JSP page using JPA-REST in back-end, I've managed to insert a blob into the database. Now I want to be able to retrieve / GET the blob from the database, but I can't seem to find any examples of how to do this via Jersey instead of using servlets(I'm pretty new to creating my own REST services).

This is the code i used to Insert blobs to the database:

@POST
@Path("upload/{id}")
@Consumes({"application/x-www-form-urlencoded", "multipart/form-data"})
public void addBlob(@PathParam("id") Integer id, @FormDataParam("file") InputStream uploadedInputStream) throws IOException {
    ClientCaseDoc entityToMerge = find(id);
    try {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int read = 0;
        byte[] bytes = new byte[1024];
        while ((read = uploadedInputStream.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }
        entityToMerge.setDocument(out.toByteArray());
        super.edit(entityToMerge);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

Is there any similar way of Retrieving a blob from the database? Or do I have to use servlets?

Any help is greatly appreciated.

MattiasH
  • 423
  • 1
  • 7
  • 20
  • @BorisPavlović I think those answers are pretty unclear to be honest, one of them created his own class PDFGenerator, the other is creating a QRCode as a PNG, and another one posting his code to export excel (xlsx) and as i mentioned in my question I don't use servlets at this moment.. – MattiasH Feb 17 '16 at 08:59
  • Of course you're using servlets. Any server side java code handling a web request is a servlet. REST makes it easier but it's still a servlet. – Boris Pavlović Feb 17 '16 at 09:09
  • @BorisPavlović Well thank you, I learned something new, now.. why do people create their own servlet classes when using REST in that case? that doesn't make sense.. – MattiasH Feb 17 '16 at 09:18
  • Hm, I'm not sure what you think of when you say servlet... – Boris Pavlović Feb 17 '16 at 09:37

2 Answers2

2

This has already been answered but to help with the wider question;

I have an entity;

@Entity
public class BlobEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "NAME")
    private String name;

    @Lob
    @Column(name="DATA", length=100000)
    private byte[] data;

A JPA repository

@Repository
public interface BlobEntityRepository extends CrudRepository<BlobEntity, Long> {
}

And a test that reads a word doc and retrieves it from the database

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")
public class BlobEntitytRepositoryTest extends AbstractTest {

    @Autowired
    private BlobEntityRepository repository;

    @Test
    @Transactional
    public void test1() throws IOException {

        InputStream inputStream = getClass().getResourceAsStream("/HelloGreg.docx");
        byte[] byteArray = IOUtils.toByteArray(inputStream);

        BlobEntity blobEntity = new BlobEntity();
        blobEntity.setName("test");
        blobEntity.setData(byteArray);

        repository.save(blobEntity);

        assertEquals(1, repository.count());

        BlobEntity entity = repository.findOne(1l);
        assertNotNull(entity);

        FileOutputStream outputStream = new FileOutputStream(new File("testOut.docx"));
        IOUtils.write(entity.getData(), outputStream);
    }

}

Config

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <context:component-scan base-package="com.greg" />
    <tx:annotation-driven />
    <jpa:repositories base-package="com.greg" />

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:file:~/data/jpa-test" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.greg" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>
Essex Boy
  • 7,565
  • 2
  • 21
  • 24
  • Is it possible to do this without using Spring and without using a JPA repository? What I have right now is an Entity class, FacadeREST, pom.xml, AbstractFacade, Application Config, JSP pages. – MattiasH Feb 17 '16 at 09:08
  • What I want to do is at the @Path("Download/{id}"), I want to find the blob connected to that {id} and send it back to the JSP page as a response – MattiasH Feb 17 '16 at 09:10
  • You need to use JPA (the API) and Hibernate (the implementation, it's very simple really, I've added spring config. – Essex Boy Feb 17 '16 at 09:13
  • I'm using JPA and jersey. – MattiasH Feb 17 '16 at 09:19
  • I suggest you create a service layer, which wraps a repository layer. You can create your service by copying the test. Jersey is just doing the front end all the request/response stuff. Everything I've shown is JPA. – Essex Boy Feb 17 '16 at 09:22
1

Is there any similar way of Retrieving a blob from the database? Or do I have to use servlets?

While not mentioned in the question, I'm taking this to be about returning a BLOB via Jersey rather than using Servlets. OP please correct me in the comments if I am wrong. If I'm correct you may wish to update your question to mention Jersey.

This question I think is a duplicate of Input and Output binary streams using JERSEY?. However the comments appear to show some confusion as to how to implement it in the OPs case. As you are loading the PDFs in the domain model (if that is a good thing I'll let other people argue over) streaming is not needed. All you need to do is create a Response with the entity set as the byte array returned by the data layer.

@Path("upload/{id}")
@GET
public Response getPDF(@PathParam("id") Integer id) throws Exception {
    ClientCaseDoc entity = find(id);
    return Response
            .ok()
            .type("application/pdf")
            .entity(entity.getDocument()) // Assumes document is a byte array in the domain object.
            .build();
}
Community
  • 1
  • 1
Michael Lloyd Lee mlk
  • 14,561
  • 3
  • 44
  • 81