How to create a multipart form post request handler in vertx - java

Hello I am using vertx in java on a standalone app to read a port in my web app. I want to get the post data from a form.
My web app has a form with a post method that I am looking to read.
My logic is
Create verticle
Create http Server
Create handler request ( it does not take all the parameters in my
code)
Listen to httpServer
Expect Multipart Request in Handler
Multimap and get form attributes
I dont know what I am missing , I am new to vertx .
For some reason I cannot post code on here.
My code:
https://pastebin.com/A1hjXFb6

Make sure that your HTML form is having enctype="multipart/form-data" attribute.
Then in your vertx code:
public class loginLogic extends AbstractVerticle {
//Vertx vertx;
private HttpServer httpServer = null;
#Override
public void start() {
Router router = Router.router(vertx);
router.route().handler(BodyHandler.create().setUploadsDirectory("uploads"));
router.post("/form").handler(ctx -> {
ctx.response().putHeader("Content-Type", "text/plain");
ctx.response().setChunked(true);
for (FileUpload f : ctx.fileUploads()) {
System.out.println("f");
ctx.response().write("Filename: " + f.fileName());
ctx.response().write("\n");
ctx.response().write("Size: " + f.size());
}
ctx.response().end();
});
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
}

Related

How to send form data(like HTTP POST) containing image and text via Rsocket?

I want the functionality similar to HTTP POST using Rsocket. Using Rsocket's request/response pattern, the data(image file and text) needs to be send and confirmation will be sent back to requester.
I tried to create a simple CustomData class to test :
RSocket Requester :
RSocketRequester req = RSocketRequester.builder()
.websocket(URI.create("ws://localhost:7000/rsocket"));
req.route("message")
.data(Mono.just(new CustomData("name", 12)), CustomData.class)
.retrieveMono(String.class).subscribe((value) -> {
System.out.println(value);
});
Message Handler:
#MessageMapping("message")
public Mono<String> response(#Payload CustomData cData) {
return Mono.just("data received!");
}
I am getting this exception :
java.lang.IllegalArgumentException: No encoder for com.demo1.demo.customdata.CustomData
Can anyone please provide an example to fulfil this?

Vertx - missing GET parameters while securing route using OAuth2

I followed this example of securing route using OAuth2 with GitHub provider: http://vertx.io/docs/vertx-web/java/#_oauth2authhandler_handler and it works fine, except missing GET parameters after request redirection.
My code:
public class MyVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
OAuth2Auth authProviderGitHub = GithubAuth.create(vertx, "<CLIENT_ID>", "<CLIENT_SECRET>");
OAuth2AuthHandler oauth2 = OAuth2AuthHandler.create(authProviderGitHub, "http://localhost:8080/callback");
oauth2.setupCallback(router.route());
router.route("/protected/*").handler(oauth2);
Handler<RoutingContext> requestHandler = (routingContext) -> {
String paramValue = routingContext.request().getParam("param");
routingContext.response().end("PARAM: " + paramValue);
};
router.get("/endpoint").handler(requestHandler);
router.get("/protected/endpoint").handler(requestHandler);
server.requestHandler(router::accept).listen(8080);
}
}
I have two simple endpoints:
/endpoint // public, without protection
and
/protected/endpoint // protected with OAuth2
When I call from a browser /endpoint with
http://localhost:8080/endpoint?param=foo
it works as expected and return PARAM: foo, whereas when I call protected endpoint with
http://localhost:8080/protected/endpoint?param=foo
it correctly redirect me to GitHub login page, then return query to my handler but without GET parameters, so response from the endpoint is PARAM: null.
Any idea what I'm doing wrong?
On vert.x <= 3.4.2 only the path was being used for the redirect, the 3.5 series has been improved and can rely on the full uri, so your code will work on that version.

Cannot send user message with Spring Websocket

I read Spring docs about user destinations.
I would like to use convertAndSendToUser method to send a message only to a particular user.
This is the java code:
#Controller
public class WebsocketTest {
#Autowired
public SimpMessageSendingOperations messagingTemplate;
#PostConstruct
public void init(){
ScheduledExecutorService statusTimerExecutor=Executors.newSingleThreadScheduledExecutor();
statusTimerExecutor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
messagingTemplate.convertAndSendToUser("myuser","/queue/test", new Return("test"));
}
}, 5000,5000, TimeUnit.MILLISECONDS);
}
}
This is the client js code:
var socket = new WebSocket('ws://localhost:8080/hello');
stompClient = Stomp.over(socket);
stompClient.connect("myuser","mypass", function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function(greeting){
showGreeting(JSON.parse(greeting.body).value);
});
stompClient.subscribe('/user/queue/test', function(greeting){
showGreeting(JSON.parse(greeting.body).value);
});
});
First of all is it correct to conside the user value this one?
stompClient.connect("myuser",...
Why this test doesn't work? This user did not receveive any message.
If I switch destination to /topic/greetings and change method to convertAndSend() this works, but obviously as broadcast and not only to particular user as requested.
Little update
I tried to setup a reply to single user with this code:
#MessageMapping("/hello")
#SendToUser("/queue/test")
public Return test(){
return new Return("test");
}
This works, this is not what I need becase this reply only to a message from client. Seems that I cannot use convertAndSendToUser() for unsollicited messaged from server.
Subscribing to /user/queue/test on the client side and using convertAndSendToUser to send a message to the /topic/test topic looks about right.
Now how are you getting the "myUser" value?
You can get this value from either request.getUserPrincipal() during the handshake, or inject the Principal when receiving a message; the sessionId works as well here. You can check this commit for more details on the matter.
Maybe its late to answer the question but for the people who may face similar issue, here is what I was missing:
The websocket URL which you are connecting to should also be a secured URL. If its not then there is no mapping between the user and the session and hence you are not able to send message to the user using convertAndSendToUser().
So, for e.g. you are connecting to the endpoint with URL pattern /hello then it should be a secured one.

Restlet and consuming/storing files

How would one handle consuming an attachment from a client POST/PUT request on the server side and store that file in a local folder, all using Restlet ?
My thoughts are as follows:
Setup Server as follows:
new MailServerComponenet.start();
public MailServer(){
getServers().add(Protocol.HTTP, 8111);
getDefaultHost().attachDefault(new MailServer());
server.getContext().getParameters().set("tracing", "true");
}
#Put
public void store(Form form){
// *And here is where I am not sure*
}
Thanks for any insight and help in advance.
Here are the following steps you should follow to implement your Restlet application:
Create a component
Component component = new Component();
Create an application and attach it on the component
component.getServers().add(Protocol.HTTP, 8182);
Application application = new MyApplication();
component.getDefaultHost().attachDefault(application);
component.start();
Configure the application within the method createInboundRoot (create a router and attach server resource on it)
public class MyApplication extends Application {
#Override
public Restlet createInboundRoot() {
Router router = new Router();
router.attach("/test", MyServerResource.class);
return router;
}
}
Implement the server resources
public class MyServerResource extends ServerResource {
#Post
public Representation handlePost(Representation repr) {
(...)
}
}
Now the global frame is implemented, I would wonder how you would send the content to Restlet. Is it simple binary content within the request payload or multi-part content?
Binary content
#Post
public Representation handlePost(FileRepresentation fileRepr) {
fileRepr.write(new FileOutputStream(
new File("/tmp/myfile.txt")));
return null;
}
Multipart content. You can have a look at this answer in this case: File Upload with Description in Restlet
Hope it helps you,
Thierry

Very peculiar :HTTP Status 405 - Method Not Allowed

[using Apache Tomcat/7.0.27]
It seems I only get this error
(HTTP Status 405 - Method Not Allowed)
when I try to make a REST request directly from the browser.
E.g by pasting this in the address bar :
http://localhost:8080/restExample/rest/catalog/video/14951/hello
When I run my test client Main.java everything works fine.
Any ideas as to why it wont let me execute a REST through the browser?
Client Side:
public class Main{
public static void main(String [] args){
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(getBaseURI(_package));
runPutRequest(service,"video/128/This is the content with the new description");
}
}
...
private static void runPutRequest(WebResource service,String path){
String response = service.path("rest/catalog/"+path).accept(MediaType.APPLICATION_XML).put(String.class);
System.out.println("Post Response :"+response);
}
Server side:
#PUT
#Path("/video/{video-id}/{short-descr}")
#Consumes(MediaType.TEXT_PLAIN)
#Produces(MediaType.APPLICATION_XML)
public Video updateVideo(#PathParam("video-id") int contentid,
#PathParam("short-descr") String descr)
{
//Video video = searchByContentId(contentid);
Video video = videoMap.get(contentid);
video.setDescription(descr);
videoMap.put(contentid,video);
if( videoMap.get(contentid) != null){
return videoMap.get(contentid);
}else{
throw new UnsupportedOperationException("NO object found");
}
}
The browser will issue a GET request for your resource - which you have declared as a #PUT on the server-side and are PUT-ing to it from your client-side code. The browser is trying to 'fetch' (or GET) the resource and nothing exists for #GET
Generally, the Browser uses GET HTTP method to make requests. Your server side component is only capable to response to PUT requests, and that’s why you get that error code.
There exist REST clients for browsers that are capable of doing PUT, POST, and DELETE requests. I prefer Simple REST Client for Chrome.

Categories

Resources