Skip to content

Commit cf05dc7

Browse files
committed
5_1_HW4_upload_chunk
1 parent a24be86 commit cf05dc7

File tree

6 files changed

+98
-18
lines changed

6 files changed

+98
-18
lines changed

parent-web/pom.xml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,47 @@
2626
<failOnMissingWebXml>false</failOnMissingWebXml>
2727
</configuration>
2828
</plugin>
29+
30+
<!-- http://stackoverflow.com/questions/4305935/is-it-possible-to-supply-tomcat6s-context-xml-file-via-the-maven-cargo-plugin#4417945 -->
31+
<plugin>
32+
<groupId>org.codehaus.cargo</groupId>
33+
<artifactId>cargo-maven2-plugin</artifactId>
34+
<version>1.6.5</version>
35+
<configuration>
36+
<container>
37+
<containerId>tomcat8x</containerId>
38+
<systemProperties>
39+
<file.encoding>UTF-8</file.encoding>
40+
</systemProperties>
41+
<dependencies>
42+
<dependency>
43+
<groupId>org.postgresql</groupId>
44+
<artifactId>postgresql</artifactId>
45+
</dependency>
46+
</dependencies>
47+
</container>
48+
<configuration>
49+
<configfiles>
50+
<configfile>
51+
<file>${masterjava.config}/context.xml</file>
52+
<todir>conf/Catalina/localhost/</todir>
53+
<tofile>context.xml.default</tofile>
54+
</configfile>
55+
</configfiles>
56+
</configuration>
57+
<deployables>
58+
<deployable>
59+
<groupId>${project.groupId}</groupId>
60+
<artifactId>${project.artifactId}</artifactId>
61+
<type>war</type>
62+
<properties>
63+
<context>${project.build.finalName}</context>
64+
</properties>
65+
</deployable>
66+
</deployables>
67+
</configuration>
68+
</plugin>
69+
2970
</plugins>
3071

3172
<resources>

persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.bertoncelj.jdbi.entitymapper.EntityMapperFactory;
44
import org.skife.jdbi.v2.sqlobject.*;
5+
import org.skife.jdbi.v2.sqlobject.customizers.BatchChunkSize;
56
import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapperFactory;
67
import ru.javaops.masterjava.persist.model.User;
78

@@ -20,11 +21,11 @@ public User insert(User user) {
2021
return user;
2122
}
2223

23-
@SqlUpdate("INSERT INTO users (full_name, email, flag) VALUES (:fullName, :email, CAST(:flag AS user_flag)) ")
24+
@SqlUpdate("INSERT INTO users (full_name, email, flag) VALUES (:fullName, :email, CAST(:flag AS USER_FLAG)) ")
2425
@GetGeneratedKeys
2526
abstract int insertGeneratedId(@BindBean User user);
2627

27-
@SqlUpdate("INSERT INTO users (id, full_name, email, flag) VALUES (:id, :fullName, :email, CAST(:flag AS user_flag)) ")
28+
@SqlUpdate("INSERT INTO users (id, full_name, email, flag) VALUES (:id, :fullName, :email, CAST(:flag AS USER_FLAG)) ")
2829
abstract void insertWitId(@BindBean User user);
2930

3031
@SqlQuery("SELECT * FROM users ORDER BY full_name, email LIMIT :it")
@@ -34,4 +35,7 @@ public User insert(User user) {
3435
@SqlUpdate("TRUNCATE users")
3536
@Override
3637
public abstract void clean();
38+
39+
@SqlBatch("INSERT INTO users (full_name, email, flag) VALUES (:fullName, :email, CAST(:flag AS USER_FLAG))")
40+
public abstract void insertBatch(@BindBean List<User> users, @BatchChunkSize int chunkSize);
3741
}

persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,11 @@ public void getWithLimit() {
3232
List<User> users = dao.getWithLimit(5);
3333
Assert.assertEquals(FIST5_USERS, users);
3434
}
35+
36+
@Test
37+
public void insertBatch() throws Exception {
38+
dao.clean();
39+
dao.insertBatch(FIST5_USERS, 3);
40+
Assert.assertEquals(5, dao.getWithLimit(100).size());
41+
}
3542
}
Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package ru.javaops.masterjava.upload;
22

3+
import com.google.common.collect.ImmutableMap;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
36
import org.thymeleaf.context.WebContext;
47
import ru.javaops.masterjava.persist.model.User;
58

@@ -19,33 +22,48 @@
1922
@WebServlet(urlPatterns = "/", loadOnStartup = 1)
2023
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 10) //10 MB in memory limit
2124
public class UploadServlet extends HttpServlet {
25+
private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
26+
private static final int CHUNK_SIZE = 2000;
2227

2328
private final UserProcessor userProcessor = new UserProcessor();
2429

2530
@Override
2631
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
27-
final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale());
28-
engine.process("upload", webContext, resp.getWriter());
32+
out(req, resp, "", CHUNK_SIZE);
2933
}
3034

3135
@Override
3236
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
33-
final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale());
34-
37+
String message;
38+
int chunkSize = CHUNK_SIZE;
3539
try {
3640
// http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html
37-
Part filePart = req.getPart("fileToUpload");
38-
if (filePart.getSize() == 0) {
39-
throw new IllegalStateException("Upload file have not been selected");
40-
}
41-
try (InputStream is = filePart.getInputStream()) {
42-
List<User> users = userProcessor.process(is);
43-
webContext.setVariable("users", users);
44-
engine.process("result", webContext, resp.getWriter());
41+
chunkSize = Integer.parseInt(req.getParameter("chunkSize"));
42+
if (chunkSize < 1) {
43+
message = "Chunk Size must be > 1";
44+
} else {
45+
Part filePart = req.getPart("fileToUpload");
46+
try (InputStream is = filePart.getInputStream()) {
47+
List<User> users = userProcessor.process(is, chunkSize);
48+
log.info("Successfully uploaded " + users.size() + " users");
49+
final WebContext webContext =
50+
new WebContext(req, resp, req.getServletContext(), req.getLocale(),
51+
ImmutableMap.of("users", users));
52+
engine.process("result", webContext, resp.getWriter());
53+
return;
54+
}
4555
}
4656
} catch (Exception e) {
47-
webContext.setVariable("exception", e);
48-
engine.process("exception", webContext, resp.getWriter());
57+
log.info(e.getMessage(), e);
58+
message = e.toString();
4959
}
60+
out(req, resp, message, chunkSize);
61+
}
62+
63+
private void out(HttpServletRequest req, HttpServletResponse resp, String message, int chunkSize) throws IOException {
64+
resp.setCharacterEncoding("utf-8");
65+
final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale(),
66+
ImmutableMap.of("message", message, "chunkSize", chunkSize));
67+
engine.process("upload", webContext, resp.getWriter());
5068
}
5169
}

web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package ru.javaops.masterjava.upload;
22

3+
import ru.javaops.masterjava.persist.DBIProvider;
4+
import ru.javaops.masterjava.persist.dao.UserDao;
35
import ru.javaops.masterjava.persist.model.User;
46
import ru.javaops.masterjava.persist.model.UserFlag;
57
import ru.javaops.masterjava.xml.schema.ObjectFactory;
@@ -16,8 +18,9 @@
1618

1719
public class UserProcessor {
1820
private static final JaxbParser jaxbParser = new JaxbParser(ObjectFactory.class);
21+
private static UserDao userDao = DBIProvider.getDao(UserDao.class);
1922

20-
public List<User> process(final InputStream is) throws XMLStreamException, JAXBException {
23+
public List<User> process(final InputStream is, int chunkSize) throws XMLStreamException, JAXBException {
2124
final StaxStreamProcessor processor = new StaxStreamProcessor(is);
2225
List<User> users = new ArrayList<>();
2326

@@ -27,6 +30,7 @@ public List<User> process(final InputStream is) throws XMLStreamException, JAXBE
2730
final User user = new User(xmlUser.getValue(), xmlUser.getEmail(), UserFlag.valueOf(xmlUser.getFlag().value()));
2831
users.add(user);
2932
}
33+
userDao.insertBatch(users, chunkSize);
3034
return users;
3135
}
3236
}

web/upload/src/main/webapp/WEB-INF/templates/upload.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
<html xmlns:th="http://www.thymeleaf.org">
12
<head>
23
<meta charset="UTF-8">
34
<title>Upload XML</title>
45
</head>
56
<body>
67
<form action="" method="post" enctype="multipart/form-data">
8+
<!--/*@thymesVar id="message" type="java.lang.String"*/-->
9+
<h2 th:if="!${message.isEmpty()}" th:text="${message}">Message</h2>
710
<h3>Select xml file to upload</h3>
811
<p>
9-
<input type="file" name="fileToUpload" id="fileToUpload"><br/>
12+
<label for="chunkSize">Chunk Size:</label>
13+
<!--/*@thymesVar id="chunkSize" type="java.lang.Integer"*/-->
14+
<input type="number" name="chunkSize" id="chunkSize" th:value="${chunkSize}" required/><br/><br/>
15+
<input type="file" name="fileToUpload" id="fileToUpload" required><br/>
1016
</p>
1117
<p>
1218
<input type="submit" value="Upload" name="submit">

0 commit comments

Comments
 (0)