Skip to content

add blobstore to webapp#5

Open
chuckluv wants to merge 1 commit intomasterfrom
CharlesDevelopment
Open

add blobstore to webapp#5
chuckluv wants to merge 1 commit intomasterfrom
CharlesDevelopment

Conversation

@chuckluv
Copy link
Copy Markdown
Owner

@chuckluv chuckluv commented Jun 9, 2020

No description provided.

System.out.println("Could not convert to int: " + maxString);
max = 1;
System.out.println("Could not convert to int|" + maxString+"|");
maxNumberOfComments = 1;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to return an error code to the caller (probably SC_BAD_REQUEST).

@WebServlet("/Comments")
public class DataServlet extends HttpServlet {
private int max=5;
private int maxNumberOfComments=5;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since maxNumberOfComments can be set concurrently by different requests, all access to this field should be synchronized. We can discuss how to do that offline.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused as to why this isn't a constant. Either it's configurable (possibly with a constant default) in which case it should be a local variable or it isn't and should be final. Seeing this random shared mutable value is a big code smell.


List<Post> comments = new ArrayList<>();
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(max);
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(maxNumberOfComments);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This read needs to be synchronized.

System.out.println("Could not convert to int: " + maxString);
max = 1;
System.out.println("Could not convert to int|" + maxString+"|");
maxNumberOfComments = 1;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This write should be synchronized.

@WebServlet("/Comments")
public class DataServlet extends HttpServlet {
private int max=5;
private int maxNumberOfComments=5;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: keep final values separate from non-final values to draw attention to the fact that they have different mutability. In this case, I would put maxNumberOfComments below all private static final fields and add a newline to separate it.

System.out.println(imageUrl);
PrintWriter out = response.getWriter();
out.println("<p>Here's the image you uploaded:</p>");
out.println("<a href=\"" + imageUrl + "\">");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's risky to manually escape values within raw HTML like this. I'll try to figure out if there's a safer way to render this (e.g., using JSPs).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using JSPs now? I'm ded.

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

// Get the URL of the image that the user uploaded to Blobstore.
String imageUrl = getUploadedFileUrl(request, "images");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that imageUrl may be null, which you should be able to handle. For example, you probably don't want to add an anchor tag with href="null". Do you want to set different HTTP response codes in this case?


// User submitted form without selecting a file, so we can't get a URL. (dev server)
if (blobKeys == null || blobKeys.isEmpty()) {
return null;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're returning null values as part of the API, you should add the @Nullable annotation tag to the method to indicate this so callers (and code linters) can see this. Alternatively, Return a java.util.Optional<String>.

return null;
}

// Our form only contains a single file input, so get the first index.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. The form only contains a single file input, but what if the user hijacked the form or manually submitted a request to submit multiple files? We probably don't need to worry about that here, but we may want to consider that during upload.


<ul id="fetch-comment"></ul>

<form id="uploaded-image" method="POST" enctype="multipart/form-data" >
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to set an action URL here? (I don't know the answer to this, but I suspect that by default, this just sends a post request to the index page URL.)

@WebServlet("/Comments")
public class DataServlet extends HttpServlet {
private int max=5;
private int maxNumberOfComments=5;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused as to why this isn't a constant. Either it's configurable (possibly with a constant default) in which case it should be a local variable or it isn't and should be final. Seeing this random shared mutable value is a big code smell.

long timestamp = System.currentTimeMillis();
String maxString = request.getParameter(MAX_COMMENTS_PARAMETER_NAME);
if (userComment != null) {
if (userComment != null ) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where's my formatter meme?

} catch (NumberFormatException e) {
System.out.println("Could not convert to int: " + maxString);
max = 1;
System.out.println("Could not convert to int|" + maxString+"|");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use String.format instead of these string concat chains.

System.out.println(String.format("Could not convert to int: \"%s\".", maxString);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moreover I'm going to cut you a bug to switch to a real logger.


//Will change when walkthrough is finished
System.out.println(imageUrl);
PrintWriter out = response.getWriter();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/formattermeme

/** Returns a URL that points to the uploaded file, or null if the user didn't upload a file. */
private String getUploadedFileUrl(HttpServletRequest request, String formInputElementName) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(request);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What fresh hell is? This API takes an HttpServletRequest?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also you don't need to actually do anything for this. Just commenting on how much I hate this API.

private String getUploadedFileUrl(HttpServletRequest request, String formInputElementName) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(request);
List<BlobKey> blobKeys = blobs.get("images");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a constant instead of inlining it if it's a keyword.

// Get the URL of the image that the user uploaded to Blobstore.
String imageUrl = getUploadedFileUrl(request, "images");

//Will change when walkthrough is finished
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you tho?

System.out.println(imageUrl);
PrintWriter out = response.getWriter();
out.println("<p>Here's the image you uploaded:</p>");
out.println("<a href=\"" + imageUrl + "\">");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using JSPs now? I'm ded.

</head>
<body onload="getComments()">
<div id="content">
<body onload="getComments()" >
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you reverse format this file?

.then((imageUploadUrl) => {
const messageForm = document.getElementById('uploaded-image');
messageForm.action = imageUploadUrl;
// messageForm.classList.remove('hidden');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants