How to get Source IP of Request in Json with Annotation? - java

Am trying to get request source ip with annotation #JsonProperty("IP") which not populating values.
Hi , I wrote web application using ResteasyBootstrap to receive and process http request with post parameters. ex: client send the product details in post parameters to server url. below is the sample
#Path("/json/Product")
public class Prodcut {
#POST
#Path("/post")
#Produces("application/json")
public Product getProductInJSON(Product product) {
System.out.println(product.toString());
String respMsg=processProduct(product);// process product
product.setResponseMessage(respMsg);
String JsonRespString=new Gson().toJson(product);
return Response.status(201).entity(JsonRespString).build();
}
public class Product{
#JsonProperty("name")
private String name;
#JsonProperty("msgid")
private String msgId;
/*setters gettes */
#Override
public String toString() {
return "{\"msgid=\":\"" + this.msgId + "\" , \"name\":\"" + this.name +""/
}";
}
now how do i get ip of client.
Suggest me

If you are looking for the client IP, then use the #Context to get the request. Then something of what is here: Getting IP address of client

Related

Troubles posting a JSON value using Spring Boot

I am trying to make a post request using json but in postman the request is successful only if I make the request like this: email#example.com. If I make a request using the standard JSON format {"email":"email#example.com"} I get "invalid email id". I should mention that content type application/json header is checked in postman, and I am making the request in body/raw.
I have tried messing with #RequestBody/#RequestParam annotations, using consumes = "application/json" but I am unsuccessful and I couldn't find a similar issue after lots of googling either.
my controller:
#RestController
public class UserController {
#Autowired
private UserService userService;
#PostMapping(value = "/forgot-password", consumes = "application/json")
public String forgotPassword(#RequestBody String email) {
String response = userService.forgotPassword(email);
if (!response.startsWith("Invalid")) {
response = "http://localhost:8080/reset-password?token=" + response;
}
return response;
}
user service:
public String forgotPassword(String email) {
Optional<User> userOptional = Optional
.ofNullable(userRepository.findByEmail(email));
if (!userOptional.isPresent()) {
return "Invalid email id.";
}
User user = userOptional.get();
user.setToken(generateToken());
user.setTokenCreationDate(LocalDateTime.now());
user = userRepository.save(user);
return user.getToken();
}
Simply put, the #RequestBody annotation maps the HttpRequest body to a transfer or domain object.You need to put object instead of String
Your endpoint should be like Below.
#PostMapping(value = "/forgot-password", consumes = "application/json")
public String forgotPassword(#RequestBody EmailDto email) {
String response = userService.forgotPassword(email.getEmail);
// ...
return response;
}
Your DTO should be like below
public class EmailDto {
private String email;
//Getters and Setters
}
You should have Email model with string property email.
public EmailPayload {
String email;
.....
Then it will work (it will fit json you provided).
Ofcouse class name can be different, only thing that must match is email property, then in your Controller your #RequestBody will be this class, and not String you have now.

Passing arguments to a dropwizard (Jersey) resource via a REST client, such as postman?

I honestly thought I knew how to do this, apparently not.
Here is my basic resource for creating a user.
#POST
#Path("create")
#Timed
#UnitOfWork
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public long createUser(#PathParam("username") String username,
#PathParam("password") String password)
{
User userToCreate = new User();
System.out.println("**********************************************");
System.out.println(username + " " + password);
System.out.println("**********************************************");
userToCreate.setUsername(username);
userToCreate.setPassword(password);
// Save to database.
return userDAO.create(userToCreate);
}
Very simple, the System.out lines are just to help me debug, they will be removed when this works (and yes, I will add encryption, too!)
Anyways, it turns out, that no matter what I seem to do - when sending data to this via PostMan, the value for username and password are ALWAYS null... I have no idea what the hell is going on.
I send the fields "username" and "password" as raw json withid the body of the request.
Am I missing something?
You have to send those parameters in the query string, not in the body. For instance:
POST http://localhost:8080/create?username=jsmith&password=foobar
Another option:
If you really want to send it in the body, create an object to hold the data.
public class UserPass {
private String username;
private String password;
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
}
And change your method signature to look like this:
public long createUser(UserPass userPass) {
User userToCreate = new User();
System.out.println("**********************************************");
System.out.println(userPass.getUsername() + " " + userPass.getPassword());
System.out.println("**********************************************");
userToCreate.setUsername(userPass.getUsername());
userToCreate.setPassword(userPass.getPassword());
// Save to database.
return userDAO.create(userToCreate);
}
Then post with JSON something like this:
{
"username": "jsmith",
"password": "foobar"
}
Be sure Content-Type is set to "application/json" on the POST request.
You are using #PathParam annotation to retrieve the inputs for your resource function but sending the data using the Body.
You need to either send the username and password as path parameters like
xyz.com/create/{username}/{password}
or
You need to create a request class and use it as input parameter to get the data from body of your request like
#Getter
#Setter
public class RegisterRequest{
private String username;
private String password;
}
And use it like
#YourAnnotations
public long create(RegisterRequest request){
//Your code for creating user.
}

How to pass #formparam in post method of URI via mozilla restclient

I have created a restful webservice in java, while testing it on mozilla restclient I am unable to pass #formparam. Can someone please help me to do the same.
Please find the code of my webservice below:
#Path("/user/service")
public class UserServices {
#GET
public String getFunc(#FormParam("username") String username) {
System.out.println("getFunc");
return username;
}
#POST
public String postFunc(#FormParam("username") String username) {
System.out.println("postFunc");
System.out.println("username is " + username);
return username;
}
}
Here is a screenshot how I am passing #formparam to the mozilla restClient:
Screenshot
Can you try changing the POST method to accept a Map (i.e. request body), e.g.:
#POST
public String postFunc(final MultivaluedMap<String, String> formParams) {
System.out.println(formParams);
}
You can then print the content of the Map and see which parameters are retrieved on the server side.

How to pass multiple parameters to Jersey POST method

I am trying to pass multiple parameters to Jersey POST method . Currently I am following below steps to pass a single parameter to Jersey POST method.
Client client = ClientBuilder.newClient();
WebTarget target= client.target("http://localhost:8080/Rest/rest/subuser").path("/insertSubUser");
SubUserBean subUserBean=new SubUserBean();
subUserBean.setIdUser(1);
subUserBean.setIdSubUserType(1);
subUserBean.setIdSubUser(15);
subUserBean.setFirstName("Haritha");
subUserBean.setLastName("Wijerathna");
subUserBean.setNumberOfDaysToEditRecord(14);
subUserBean.setUserName("haritha");
subUserBean.setPassword("hariwi88");
subUserBean.setDateCreated(Common.getSQLCurrentTimeStamp());
subUserBean.setLastUpdated(Common.getSQLCurrentTimeStamp());
target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(subUserBean, MediaType.APPLICATION_JSON_TYPE));
SubUserJSONService.java
#Path("/subuser")
public class SubUserJSONService {
#POST
#Path("/insertSubUser")
#Consumes(MediaType.APPLICATION_JSON)
public String updateSubUser(SubUserBean bean){
SubUserInterface table = new SubUserTable();
String result= table.insertSubUser(bean);
return result;
}
}
Now, I want to pass parameters to following method via Jersey POST method.
public String insertHistory(List<SocialHistoryBean> list, String comment){
//my stuffs
}
Have any ideas to do above work ?
Thank you.
You can try using MultivaluedMap.Add form data and send it to the server. An example below, code is not tested just for demo/logic flow.
WebTarget webTarget = client.target("http://www.example.com/some/resource");
MultivaluedMap<List, String> formData = new MultivaluedHashMap<List, String>();
formData.add(List, "list1");
formData.add("key2", "value2");
Response response = webTarget.request().post(Entity.form(formData));
Consume this on server side something like
#Path("/uripath")
#POST -- if this is post or #GET
#Consumes("application/x-www-form-urlencoded;charset=UTF-8") or json..
#Produces("application/json")
public void methodNameHere(#FormParam("list") List<String> list1, #FormParam("key2") String val2) {
System.out.println("Here are I am");
System.out.println("list1" + list1.size);
System.out.println("val2" + val2);
}
Read more here in docs..
In case you're using Jersey 1.x, check this example on how to post multiple objects as #FormParam
Client: (pure Java):
public Response testPost(String param1, String param2) {
// Build the request string in this format:
// String request = "param1=1&param2=2";
String request = "param1=" + param1+ "&param2=" + param2;
WebClient client = WebClient.create(...);
return client.path(CONTROLLER_BASE_URI + "/test")
.post(request);
}
Server:
#Path("/test")
#POST
#Produces(MediaType.APPLICATION_JSON)
public void test(#FormParam("param1") String param1, #FormParam("param2") String param2) {
...
}
JSON data cannot be passed to the server in a List. This means that you should create a wrapper around your SocialHistoryBean class (i.e around the list that holds your objects)
#XmlRootElement(name = "uw")
public class SocialHistoryBeanWrapper implements Serializable {
private List<SocialHistoryBean> sList ;//this will hold your SocialHistoryBean instances
public SocialHistoryBeanWrapper(){
sList = new ArrayList<User>();
}
public List<User> getUsrList(){
return sList;
}
}
Your server side code will be like
#POST
#Path("/history")
#Produces(MediaType.TEXT_PLAIN)
#Consumes(MediaType.APPLICATION_JSON)
public String insertHistory( #QueryParam("comment") String comment, SocialHistoryBeanWrapper uw) {
do whatever you want with your history data
//userData.setUser(uw.getUsrList().get(0));
return comment; //just echo the string that we have sent from client
}
Note that comment is passed with #QueryParam (this means it's not part of the POST request (body) but is rather encoded in the URL string. For this to work, you can call your service as (the client code)
WebTarget target = client.target(UriBuilder.fromUri("http://localhost:8088/Rest/rest/subuser").build());
SocialHistoryBeanWrapper uw = new SocialHistoryBeanWrapper();
//just populate whatever fields you have;
uw.getUsrList().get(0).setName("Mark Foster");
uw.getUsrList().get(0).setProfession("writer");
uw.getUsrList().get(0).setId(55);
String s = target.path("history").queryParam("comment", "OK").request()
.accept(MediaType.TEXT_PLAIN).post(Entity.entity(uw, MediaType.APPLICATION_JSON), String.class);
System.out.println(s);//this prints OK

Spring catch all response types

I'm currently building a REST client which has pretty much the exact same code as in the Consuming a RESTful Web Service guide. This simple example works excellently when receiving valid JSON responses but since I'm also developing the webservice I wanted to be able to capture the raw response contents in case the response isn't valid JSON (without having to send the request twice).
So basically the guide boils down to this code:
RestTemplate restTemplate = new RestTemplate();
Page page = restTemplate.getForObject("http://graph.facebook.com/gopivotal", Page.class);
System.out.println("Name: " + page.getName());
System.out.println("About: " + page.getAbout());
System.out.println("Phone: " + page.getPhone());
System.out.println("Website: " + page.getWebsite());
And is based on this class:
package hello;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown = true)
public class Page {
private String name;
private String about;
private String phone;
private String website;
public String getName() {
return name;
}
public String getAbout() {
return about;
}
public String getPhone() {
return phone;
}
public String getWebsite() {
return website;
}
}
Now imagine that the response is NOT valid JSON (due to a mistake in the webservice or so) or even that the response type is not application/json, how can I log the response body as plain text? I.e. how can I access the response body as plain text when this line fails:
Page page = restTemplate.getForObject("http://graph.facebook.com/gopivotal", Page.class);
PS: I came across this question - which never got answered - and though I'm not sure, I think the actual intent of that code corresponds with my question as well.
You have to implement your custom ResponseErrorHandler and plug it into your RestTemplate bean.
something like:
public class LogResponseErrorHandler implements ResponseErrorHandler {
...
#Override
public void handleError(ClientHttpResponse response) throws IOException {
logResponse(response.getBody());
}
...
}
an article about the concrete usage of ResponseErrorHandler:

Categories