Comments (18)
@wanglunhui2012 I could suggest the following:
In your code, check when the request arrived (first HttpRequest) if the request is one of Content-Type: application/x-www-form-urlencoded
or Content-Type: multipart/form-data;boundary="xxx"
.
- If yes : use standard
HttpPostRequestDecoder
which handles one or the other - If no : use an
HttpObjectAggregator
to return BODY object as is, since it is not a request
In the example given by @sd205 , this is not a request but a simple JSON, so a simple body.
from blade.
See also netty/netty#11985
from blade.
can you show the core code that can reappear this error.
from blade.
What do you mean by core code? As I say, the request isn't reaching my code, so it's not material. I've raised an issue on netty, as noted above. Apart from that all I have is the stack trace, which I have shared.
from blade.
In my code, i can't reappear this error . blade-mvc version is 2.0.15.RELEASE.
public static void main(String[] args) {
Blade.of().listen(8080).post("/body", ctx -> {
System.out.println("body string is:" + ctx.bodyToString());
}).start();
}
curl -X POST http://localhost:8080/body -d '{"formatString=":"=","delimiters=":null,"params":["","","","","","","","","",""]}'
the console print:
body string is:{"formatString=":"=","delimiters=":null,"params":["","","","","","","","","",""]}
from blade.
test-case.zip
See the attached test case:
mvn package
java -jar target\blade-test-case.jar
GET http://localhost:9000/static/index.html
POST http://localhost:9000/test {"str":"="}
from blade.
how do you send the post request? i try the code, no problem, no error.
from blade.
Interesting! I have tested from a react app using Axios and from Postman. In both cases it works fine until I add an = to the string, i.e. {"str":"a"} works but {"str":"a="} fails. Both add various headers, so I'm trying now with CURL (new build attached):
curl -i http://localhost:8999/static/index.html
curl -X POST http://localhost:8999/test -d {"str":"abc"} // this works
curl -X POST http://localhost:8999/test -d {"str":"ab="} // this fails with
2022/01/13 10:30:30 ERROR [ worker@thread-5 ] c.b.m.h.DefaultExceptionHandler : com.blade.kit.json.ParseException: {str:ab= (7):Expected a ',' or '}'
at com.blade.kit.json.SampleJsonSerializer.nextValue(SampleJsonSerializer.java:118)
at com.blade.kit.json.SampleJsonSerializer.deserialize(SampleJsonSerializer.java:84)
at com.blade.kit.json.DefaultJsonSupport.formJson(DefaultJsonSupport.java:22)
at com.blade.kit.JsonKit.formJson(JsonKit.java:52)
at com.blade.mvc.handler.RouteActionArguments.getBodyParam(RouteActionArguments.java:152)
at com.blade.mvc.handler.RouteActionArguments.getAnnotationParam(RouteActionArguments.java:120)
at com.blade.mvc.handler.RouteActionArguments.getRouteActionParameters(RouteActionArguments.java:46)
at com.blade.mvc.RouteContext.injectParameters(RouteContext.java:585)
at com.blade.server.netty.RouteMethodHandler.handle(RouteMethodHandler.java:79)
at com.blade.server.netty.HttpServerHandler.executeLogic(HttpServerHandler.java:159)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:591)
at java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:456)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.lang.Thread.run(Thread.java:748)
curl -X POST http://localhost:8999/test -d '{"str":"ab="}' // fails with:
2022/01/13 10:37:30 ERROR [ worker@thread-10 ] c.b.m.h.DefaultExceptionHandler : java.lang.ClassCastException: java.lang.String cannot be cast to test.TestRouter$StringBean
at test.TestRouterMethodAccess.invoke(Unknown Source)
at com.blade.reflectasm.MethodAccess.invoke(MethodAccess.java:43)
at com.blade.server.netty.RouteMethodHandler.routeHandle(RouteMethodHandler.java:256)
at com.blade.server.netty.RouteMethodHandler.handle(RouteMethodHandler.java:87)
at com.blade.server.netty.HttpServerHandler.executeLogic(HttpServerHandler.java:159)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:591)
at java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:456)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.lang.Thread.run(Thread.java:748)
I tried with --data-urlencode, didn't help. I tried escaping the equals with a backslash, that just hung.
from blade.
@sd205 Is it possible that you missused POST request?
POST request shall be either:
-
URL encoded form (as in GET format but in body)
Content-Type: application/x-www-form-urlencoded Content-length=nn field1={"str":"ab="}
so through but with data-encoding only for left part of 'field1={"str":"ab="}' (not 100% sure curl command)
curl -X POST http://localhost:8999/test -F field1='{"str":"ab="}'
-
Through multipart
Content-Type: multipart/form-data;boundary="boundary" --boundary Content-Disposition: form-data; name="field1" {"str":"ab="} --boundary--
so with curl (not 100% sure curl command)
curl -X PUT URL \
--header 'Content-Type: multipart/form-data; boundary=---------BOUNDARY' \
--data-binary @file
where file is the file containing {"str":"ab="}
-
native (text or binary)
Content-Type: text/plain
Content-length=nn{"str":"ab="}
as you did but then there is no decoding at all (no data, either url form or multipart form), just binary.
Therefore, when it tries to decode the content, it first search for the first 'equal' sign, since not multipart, and find it within "value" since there is no field declared first.
from blade.
Thanks both for your help!
I've also tried with Content-Type: application/json...
This works fine:
curl -X POST http://localhost:8999/test -H "Content-Type: application/json" -d {"str":"abc"}
But this fails with the ParseException:
curl -X POST http://localhost:8999/test -H "Content-Type: application/json" -d {"str":"ab="}
If I add Content-Length it just hangs, e.g.:
curl -X POST http://localhost:8999/test -H "Content-Type: application/json" -H "Content-Length: 13" -d {"str":"abc"}
If I add Content-Length and get the JSON from a file, it works if the file contains {"str":"abc"}:
curl -X POST http://localhost:8999/test -H "Content-Type: application/json" -H "Content-Length: 13" -d @test.json
But it hangs when the file contains {"str":"ab="}
Any other suggestions of things to try?
from blade.
You still send a "binary" content (whatever the content-type
to application/json
).
Unde the wood: the decoder tries to find out "varname=value" while you provide only "value".
Therefore, when "value" contains '=', it believes this is the delimiter of the varname, but then your varname is {"str":"ab
which is incorrect from HTTP point of vue (only letter and number, with at least one letter at first pos, probably including some others like '_' or '-' but in ASCII).
As the implementation behind is using a default Factory which uses disk storage, the varname is used as part of the filename. But some characters are not allowed for filename, so the error.
The main point is: you don't send a form, but a binary content. The decoder should not be used in this case (as if you send a PNG file without any form context).
If you want to send a form, you have to change your input, either using the Url encoded form or the multipart form (point 1 or 2 in my previous answear).
from blade.
Thanks for explanation - though I'm still not clear where the problem is, whether someone is going to fix something or whether I can send the request (from react/axios not just curl) in a different way to get the required behaviour.
Again, I am sending a valid JSON object as the request body and specifying application/json. There's no reason for the server-side code to start parsing this like a form and tripping over the = signs.
Until now I found Blade a very neat solution to my needs, but this is quite problematic for me as sending an = in the JSON body is a fairly common scenario in my application.
from blade.
@sd205 I don't know much Blade, but I think you missused it.
According to the stack traces, Blade is expecting a Form request (either var=value&var2=value2 with url encoding for value, either multipart form with delimiter-definition of var-content value-delimiter-definition of var2-content value2-end delimiter).
You are sending a simple Json object, but this is not a Form (no variable defined).
Meybe a missused of Blade ? @wanglunhui2012
from blade.
It appears to be a documented capability, see: https://github.com/lets-blade/blade#body-parameters "Body Parameter To Model"
However, I note that their examples wrap the JSON in single quotes, which gives me a ClassCastException, as noted above:
curl -X POST http://localhost:8999/test -H "Content-Type: application/json" -d '{"str":"abc"}'
from blade.
In case of simple body, not a form, so not when Content-Type: application/x-www-form-urlencoded
or Content-Type: multipart/form-data;boundary="xxx"
I guess that Blade should not used the default HttpPostRequestDecoder
but a simple Body to String content like HttpObjectAggregator
to get the body content and then uses it as needed.
My 2 cents
from blade.
@wanglunhui2012 anything to suggest?
from blade.
@wanglunhui2012 it's gone quiet on this issue, what are the next steps please?
from blade.
Anyone?
from blade.
Related Issues (20)
- Consuming Third party Rest resource HOT 6
- 刀片启动时Netty中的NoSuchMethodError
- SimpleIoc类ConcurrentHashMap没导包
- 有木有人,有兴趣把这个框架盘活,维护起来。交给社区日常维护。 HOT 8
- No JSON response body HOT 13
- bean的bug HOT 1
- Feature: create a scaffolding project
- 你好,更新后@WebSocket注解失效
- [BUG]: defaultValue for annotation @PathParam does not seem to be working
- 请求流水号串联跟踪日志
- failed: Too many open files error issue HOT 1
- 2.1.2 RELEASE static resources 500 substring error -1 HOT 2
- Cannot use this project HOT 1
- 文档问题
- 计划支持jdk11,jdk17吗? HOT 1
- Can you support blueprint like Python flask framework Or something like app submodule?
- Error 500 in Docker, RouteActionArguments
- 您好,是否有计划支持java17以及21版本
- HelloGitHub Badge
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blade.