How 400 BAD_REQUEST java api Put with exchangeToMono? - java

I have a java application that calls another application it works well for the exist get function my generate this error 400 BAD_REQUEST when I try to create with a Put function.
curl -XPUT URLSERVER2/users/usernameToBeUsed \
-d '{"password":"passwordToBeUsed"}' \
-H "Content-Type: application/json"
#Service
public class Server2Api {
#Value("${source.server2.base.url}")
private String baseUrl;
Logger log = LoggerFactory.getLogger(getClass());
private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(1);
private final WebClient localApiClient;
public Server2Api(WebClient.Builder localApiClient) {
this.localApiClient = localApiClient.baseUrl(baseUrl).build();
}
public ResponseEntity<Void> creatUser(String username, String pwd){
String body = "{'password':'"+ pwd +"'}";
return localApiClient
.put()
.uri(baseUrl+"/users/"+username )
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchangeToMono(
response -> response.toBodilessEntity()
)
.block(REQUEST_TIMEOUT);
}
}
I just try to change "{'password':'"+ pwd +"'}" to "{password:'"+ pwd +"'}".
with Postman resquest works. URL is ok work on get function

Related

Spring is refusing to send a ResponseEntity but does not throw exceptions

My POJO/data model:
public class CanResendResponse {
#JsonProperty(value = "canResend")
#NotEmpty
public Boolean canResend;
// getters, setters & ctors
}
My Spring Boot controller & method:
#RestController
#RequestMapping("v1/data/fizzes")
class FizzResource {
#GetMapping(value = "{fizzId}/canResend")
public void canResendVerifications(#PathVariable(value = "fizzId") String fizzId) {
Fizz fizz = fizzRepository.findById(fizzId);
Boolean canResend;
System.out.println("Fizz name:" + fizz.getName());
if(fizz.canResend()) {
canResend = Boolean.TRUE;
} else {
canResend = Boolean.FALSE;
}
return new ResponseEntity<CanResendResponse>(new CanResendResponse(canResend), HttpStatus.OK);
}
}
My curl command:
curl -H "Content-Type: application/json" -X GET https://localhost:9200/v1/data/fizzes12345/canResend
When I run the curl command I don't see any exceptions/error on the server side and the curl completes without error but I do not see the expected HTTP response entity, like:
{
"canResend" : "true"
}
However I do see the Fizz name: Joe message in STDOUT.
I've confirmed the same behavior in a browser (I punch https://localhost:9200/v1/data/fizzes12345/canResend) into a browser and the response/page is empty. Any ideas as to what I can do to fix this?
Your method has VOID return type. Try this:
#GetMapping(value = "{fizzId}/canResend")
public ResponseEntity canResendVerifications(#PathVariable(value = "fizzId") String fizzId) {
Your method code goes here...
}
Change
public void canResendVerifications(#PathVariable(value = "fizzId") String fizzId) {
to
public ResponseEntity<> canResendVerifications(#PathVariable(value = "fizzId") String fizzId) {
... and make sure you return that ResponseEntity.

Apache CXF Spring rest service POST request returns "msg" : "Stream closed"

I work with an Apache Cxf, Spring Jax-rs service and I have the following service definition and the implementations provided,
THE DEFINITION
#POST
#Path("/generateAddress")
#Consumes(MediaType.APPLICATION_JSON)
#Produces({MediaType.APPLICATION_JSON})
WalletInfo generateAddress(final String walletName, String currencyName);
THE IMPLEMENTATIONS
public synchronized WalletInfo generateAddress(final String walletName, String currencyName) {
WalletInfo walletInfo = IWalletInfoDao.getWalletInfoWithWalletNameAndCurrency(walletName, currencyName);
return walletInfo;
}
When I do the POST request with the cURL like
curl -H "Content-Type: application/json" -X POST -d '{"walletName":"Icecream5500","currencyName":"Bitcoin"}' http://localhost:8080/api/rest/wallet/generateAddress
I get the JSON response back,
{
"msg" : "Stream closed",
"date" : "2017-08-28T09:22:027Z"
}
I'm pretty sure that the generateAddress method works fine. What is
the issue here and particularly, when you would get the message Stream closed in the Spring Apache Cxf project while doing the POST requests? Obviously, I can provide more info if required. The server log is normal and I see nothing unusual.
The POST body doesn't match with the parameters of the method and this created the issue in the first place. I have solved the problem in the following options.
I created a new class
public class CreateWalletWithNameAndCurrency {
String walletName;
String currencyName;
public CreateWalletWithNameAndCurrency(String walletName, String currencyName) {
this.walletName = walletName;
this.currencyName = currencyName;
}
public CreateWalletWithNameAndCurrency() {
}
public String getWalletName() {
return walletName;
}
public String getCurrencyName() {
return currencyName;
}
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
public void setWalletName(String walletName) {
this.walletName = walletName;
}
}
I changed the definition of the POST request like this,
#POST
#Path("generateAddress")
#Consumes(MediaType.APPLICATION_JSON)
#Produces({MediaType.APPLICATION_JSON})
WalletInfo generateAddress(CreateWalletWithNameAndCurrency createWalletWithNameAndCurrency);
The implementation is provided below,
public synchronized WalletInfo generateAddress(CreateWalletWithNameAndCurrency createWalletWithNameAndCurrency) {
String walletName = createWalletWithNameAndCurrency.getWalletName();
String currencyName = createWalletWithNameAndCurrency.getCurrencyName();
WalletInfo walletInfo = iWalletInfoDao.getWalletInfoWithWalletNameAndCurrency(walletName, currencyName);
// some more code
}
Finally, I can do the POST request like this,
curl -H "Content-Type: application/json" -X POST -d '{"walletName":"Copenhangen","currencyName":"Bitcoin"}' http://localhost:8080/rest/wallet/generateAddress

Jersey PathParam with HTTP 405 error

I'm using jersey for my rest server, and I got a HTTP 405 error, when I try to forward POST request to relative GET resource.
#Path("/")
public class MyResource {
#POST
#Path("/{method}")
#Produces(MediaType.APPLICATION_JSON)
public String postRequest(#PathParam("method") String method, #Context UriInfo uriInfo, String body) throws IOException {
JsonParser parser = new JsonParser();
JsonObject root = parser.parse(body).getAsJsonObject();
JsonObject params = root;
if (root.has("method")) {
method = root.get("method").getAsString();
params = root.getAsJsonObject("params");
}
UriBuilder forwardUri = uriInfo.getBaseUriBuilder().path(method);
for (Map.Entry<String, JsonElement> kv : params.entrySet()) {
forwardUri.queryParam(kv.getKey(), kv.getValue().getAsString());
}
return new SimpleHttpClient().get(forwardUri.toString());
}
#GET
#Path("/mytest")
#Produces(MediaType.APPLICATION_JSON)
public String getTest(#QueryParam("name") String name) {
return name;
}
}
curl -X POST -d {"method":"mytest","params":{"name":"jack"}} localhost/anythingbutmytest
curl -X GET localhost/mytest?name=jack
These two curl above work fine. But I get a 405 error , when I try to request like this:
curl -X POST -d {"method":"mytest","params":{"name":"jack"}} localhost/mytest
javax.ws.rs.NotAllowedException: HTTP 405 Method Not Allowed
at org.glassfish.jersey.server.internal.routing.MethodSelectingRouter.getMethodRouter(MethodSelectingRouter.java:466)
at org.glassfish.jersey.server.internal.routing.MethodSelectingRouter.access$000(MethodSelectingRouter.java:94)
......
What should I do?
-------------------------------------Update-------------------------------------
curl -X POST -d {"method":"mytest","params":{"name":"jack"}} localhost/mytest
This curl work fine, when I add a post method like below. But I will write a same POST method for every GET Method like that, is there any other solution?
#POST
#Path("/mytest")
#Produces(MediaType.APPLICATION_JSON)
public String postMyTest(#Context UriInfo uriInfo, String body) throws Exception {
return postRequest(uriInfo.getPath(), uriInfo, body);
}
Besides, is there any other way to re-route POST request to a method in the same class without building a new HTTP request?
You should make
#POST
#Path("/mytest")
and not "getTest" method.Reason is below.
Command
curl -X POST -d {"method":"mytest","params":{"name":"jack"}} localhost/anythingbutmytest
will accept because of
#Path("/{method}") .
But
curl -X POST -d {"method":"mytest","params":{"name":"jack"}} localhost/mytest
will not accept because of
#GET
#Path("/mytest")
POST does not match GET.

Required request body is missing

I am new at Spring and Rest.
I wrote a simple rest like this:
#RequestMapping(value = "/loginTest", method = RequestMethod.POST)
#ResponseBody
public Response loginTest(#RequestBody LoginRequest request) {
System.out.println("enter loginTest.");
String account = request.getAccount();
String password = request.getPassword();
Response res = new Response();
return res;
}
And the LoginRequest is like this:
public class LoginRequest {
private String account;
private String password;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
When I test this via command:
curl -X POST "{"account": "aaa","password": "bbb"}" -H "Content-type:application/json" http://localhost:8080/user/loginTest
But I got the result:
[1/2]: account: aaa --> <stdout>
--_curl_--account: aaa
curl: (6) Could not resolve host: account; nodename nor servname provided, or not known
{
"timestamp" : "2015-12-30T16:24:14.282+0000",
"status" : 400,
"error" : "Bad Request",
"exception" : "org.springframework.http.converter.HttpMessageNotReadableException",
"message" : "Bad Request",
"path" : "/user/loginTest"
}
And also in eclipse console:
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.test.response.Response com.test.service.UserService.loginTest(com.test.model.request.LoginResquest)
Does the class LoginRequest need an annotation? Because the Jason cannot be converted to a class?
Would anyone help me figure this out?
Request body should be sent in --data switch, in curl.
See this https://superuser.com/questions/149329/what-is-the-curl-command-line-syntax-to-do-a-post-request
So your request should now become
curl -X POST --data '{"account": "aaa","password": "bbb"}' -H "Content-Type:application/json" http://localhost:8080/user/loginTest
Also if you can run a browser on the machine where you're sending the requests from, then you can try some REST client plugins. They're way easier to use and provide saving requests and history features.
Check this plugin

BadRequestException in JAX-RS endpoint

I have the following endpoint declared in my JAX-RS application:
#WebService
public interface AlertWeb
{
#POST
#Path("/add")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public StringResponse addAlert(String name,
int amount, String timespan, String repo, String action);
}
I'm using the following curl command to call this endpoint:
curl -X POST -H "Cache-Control: no-cache"
-H "Content-Type: application/x-www-form-urlencoded"
-d "name=yellow&amount=2&timespan=DAY&repo=A&action=%7Baction%3A'GreenDivAction'%2C+message%3A'Simple+Message'%2C+args%3A+%5B'arg1'%2C'arg2'%5D%7D"
http://localhost:8080/AdminService/alert/add
but keep getting the following error when I make the request:
javax.ws.rs.BadRequestException: java.lang.NumberFormatException: For input string: ""
Note Line breaks in curl syntax added for readability.
What am I doing wrong?
You will need to add #FormParam to your method parameters if you want them to be injected as such
#POST
#Path("/add")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response addAlert(
#FormParam("name") String name,
#FormParam("amount") int amount,
#FormParam("timespan") String timespan,
#FormParam("repo") String repo,
#FormParam("action") String action) {
}

Categories

Resources