keananf / photosharewebapp Goto Github PK
View Code? Open in Web Editor NEWWeb-based client and RESTful server built with Jersey and Grizzly
Web-based client and RESTful server built with Jersey and Grizzly
Server / client side components.
This would also server as a mechanism to add / delete descriptions as well.
This will follow a similar model to Comment votes, in that there will be a separate table storing associations. That is, a photo_id, a user_id, and a boolean indicating a up / down vote.
Searching for Users.
Perhaps in the future, allow for the ability to search for albums / specific photos
By API
Server-side component mostly finished. Will need logic to reject large photos, given an arbitrary, configurable size limit ('X' MB).
Supported file types (?) : PNG, JPG, GIF
This is mostly completed, however uploading a photo will now also require an album_id.
This will mandate adding a foreign key reference to 'album_id' in the 'photos' table, and changing relevant APIs to expect an 'album_id.'
The server-side component will follow a similar structure to how photos and comments are retrieved by id.
I believe it's a ID generation issue. The first Album created has ID of 0, and then the second ones throws an Exception:
org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.ALBUMS(ALBUMID)";
Full trace:
INSERT INTO albums(albumId,albumName,username,albumDescription,albumTime) values(?, ?, ?, ?, ?) [23505-171]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.index.PageDataIndex.getNewDuplicateKeyException(PageDataIndex.java:161)
at org.h2.index.PageDataIndex.add(PageDataIndex.java:139)
at org.h2.table.RegularTable.addRow(RegularTable.java:122)
at org.h2.command.dml.Insert.insertRows(Insert.java:124)
at org.h2.command.dml.Insert.update(Insert.java:84)
at org.h2.command.CommandContainer.update(CommandContainer.java:75)
at org.h2.command.Command.executeUpdate(Command.java:230)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:156)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:142)
at server.datastore.DatabaseBackedDataStore.persistAddAlbum(DatabaseBackedDataStore.java:230)
at server.datastore.RequestResolver.addAlbum(RequestResolver.java:206)
at server.restApi.AlbumsApi.addAlbum(AlbumsApi.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:377)
at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:745)
Registers a new user to follow.
This has both a server / client-side component
Explicit server-side API, and client component
Decide on front-end frameworks and libraries to use.
Look at VueJS, Bootstrap 3/4, useful npm packages if we're using npm.
Assuming we will not use webpack or similar tools.
Server-side component already completed
Server-side component already completed
This is similar to retrieving all photos / comments made by a particular user.
This API will retrieve photos from users who the given user is following.
This will delete from the database, and cascade delete with comments
Server / client side components
For proper security, HTTPS should be used. Some research needs carried out for this, including setting up certificates, etc.
Login: the restSpec says the endpoint is POST
, but trying to post to that method I get Method Not Allowed
- the wadl
files also suggests it's a GET
endpoint. As per previous discussion, can we make this endpoint not require the auth headers, because I need to validate the user's details for login before making the auth token, and need to receive hashed password from the server to avoid different hashing on the front-end and back-end.
Register: Sending POST
request to the endpoint with following data: {username: "test", password: "test"}
throws Exception in the server console log:
org.h2.jdbc.JdbcSQLException: NULL not allowed for column "USERNAME"; SQL statement:
INSERT INTO users(username,password,admin) values(?, ?, ?) [23502-171]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.table.Column.validateConvertUpdateSequence(Column.java:293)
at org.h2.table.Table.validateConvertUpdateSequence(Table.java:692)
at org.h2.command.dml.Insert.insertRows(Insert.java:120)
at org.h2.command.dml.Insert.update(Insert.java:84)
at org.h2.command.CommandContainer.update(CommandContainer.java:75)
at org.h2.command.Command.executeUpdate(Command.java:230)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:156)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:142)
at server.datastore.DatabaseBackedDataStore.persistAddUser(DatabaseBackedDataStore.java:406)
at server.datastore.RequestResolver.addUser(RequestResolver.java:249)
at server.restApi.UsersAPI.addUser(UsersAPI.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:377)
at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:745)
Information to include:
Server / client side components.
This would also server as a mechanism to delete descriptions as well.
This will entail simple text replacement, for implementation's sake.
Server-side component completed.
This will delete from the database, and cascade delete with replies
Server side component mostly completed.
Need to figure out authentication with iOS
Server / client-side APIs allowing a user to un-follow another
Login/logout & register functionality.
Automatically send Auth headers to API endpoints when user is logged in.
This might be helpful:
https://stackoverflow.com/questions/32093217/static-content-in-grizzly-jersey
The contents from web_client
should be loaded statically via the server. For example, /photoshare/index.html
should return the contents of web_client/index.html
and so on.
Reason for this is that running the server will provide the client as well. I.e. loading up the homepage (http://localhost:8080/photoshare/
) will show up the client.
The server-side component is already finished.
A separate page where users will be able to see a list of all albums they have created and add new ones.
This will delete from the database, and cascade delete with comments
users
Getting all users: GET /users
Fetching a user: GET /users/{id}
or GET /users/{username}
Creating a user POST /users
Updating a user PUT /users/{id}
or PATCH /users/{id}
Deleting a user DELETE /users/{id}
Explicit server-side API, as well as client component
Simple move the auth information from message body into header
On the POST /users/login
endpoint, on success, can it return a User object (like ones in GET /users/
) as the client needs to know the info about the user when they log in (for example, whether they're an admin).
Optionally, it would be useful if it returned an error message otherwise (something I can feed back to the user).
Notification will need removed when list of followers retrieved.
This table will hold associations, and could be as simple as rows with two elements each: the user following as well as the user being followed.
This will entail a server / client side component, and will follow a similar model to voting on a comment.
A potential endpoint could be: /photos/upvote/{id}
This will allow us to track which album a photo belongs to
This will delete from the database, and cascade delete with comments / replies
Create an endpoint for retrieving raw bytes
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.