How to access form parameters using RestEasy REST.Request? - java

I have my form below:
<form id="form1" name="form1">
<fieldset>
<ol>
<li>
<label>Project:</label>
<select id="project" name="project" required></select>
</li>
</ol>
<input type="button" onclick="request();">
</fieldset>
</form>
I created a request() function on the onclick event of the input button. I changed the input type to button because I didn't want the page to reload.
The request function uses the RestEasy REST.Request class to create a custom rest request. I used setEntity on the REST.Request object but I don't know how to access that information on the server side.
Below is the request function:
request: function() {
var myRequest = new REST.Request();
var form1 = document.forms["form1"];
var projectTxt = form1.elements["project"].value;
myRequest.setURI(REST.apiURL + "/request/item");
myRequest.setMethod("GET");
myRequest.setEntity({project:projectTxt});
myRequest.execute(function(status, request, entity) {
if (status === 200 && request.readyState === 4) {
// entity is always null
sessionStorage.setItem("project", entity);
console.log("entity=" + entity);
}
});
},
In the above code, entity in the function passed to myRequest.execute() is always null.
Here is the Java code:
#Path("item")
#GET
public String itemFormatRequest(#FormParam("project") String project)
{
// project is always null
return "blarg!!! project is " + project;
}
In the above code, project is null. I've tried using #QueryParam and that doesn't work either. Am I just using this incorrectly or is there something else I'm missing? I've done much trial and error by changing #GET to #POST in both the javascript and java codes. Have also tried adding #Consumes("application/x-www-form-urlencoded") in the java code and that didn't work.
The only thing I did get to work is adding query parameters to the REST.request object like this:
myRequest.addQueryParameter("project", projectTxt);
And then I'm able to retrieve this using (#QueryParam("project") String project).
Thanks!

You are using GET as request method. A GET is intended to retrieve data and so you don't pass an entity. If you just want to read data of a selected project you can use a GET in conjunction with a #QueryParam. But then you don't pass an entity. Just add the queryParameter:
myRequest.addQueryParameter('project', projectTxt);
If you want to pass data to the server you should change the method of the request to POST (in the client and the server code). Also your entity is JSON but your server code expects a #FormParam. The REST.Request object has a addForm and add addFormParameter method. So one of the following should also work (untested):
myRequest.addForm('form1', form1);
or
myRequest.addFormParameter('project', projectTxt);

Related

React REST request to Java backend failing

I have a simple React form. I am trying to send the data from this form using Fetch API to my Java backend. Here is my React Form file:
import React, {Component} from 'react';
class Form extends Component {
constructor(props){
super(props);
this.state={value:""};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event){
event.preventDefault();
this.setState({value:event.target.value});
}
handleSubmit(event){
event.preventDefault();
const data = new FormData(event.target);
fetch('http://localhost:8080/add/person', {
method: 'POST',
body: data
});
}
render(){
return(
<form onSubmit={this.handleSubmit}>
<label>Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit"/>
</form>
);
}
}
For some reason, the data variable always has an empty JSON when I am in debug mode. In my Java backend, when I receive the request, I am seeing blank form data.
Any ideas as to why I am not able to send data across to my Java backend?
EDIT: I would also like to point out that my frontend is hosted on localhost:3000, while my Java backend server is on localhost:8080
why not just submit your data using the value stored in state?
handleSubmit(event){
event.preventDefault();
const data = this.state.value; //change here
fetch('http://localhost:8080/add/person', {
method: 'POST',
body: data
});
}
UPDATE: in your package.json add "proxy": "http://localhost:8080" if that doesn't work you will have to open it up using something like this but for what ever framework you're using on your backend.
https://www.npmjs.com/package/cors#enabling-cors-pre-flight
http://www.baeldung.com/spring-cors
as #Tadas Antanavicius said your input is also missing a name value. here is a nice and short medium article on the react portion of what you are trying to do with your code. you can even remove your onChange from your input field.
https://medium.com/#everdimension/how-to-handle-forms-with-just-react-ac066c48bd4f
Your problem is unrelated to your backend - the fetch code looks correct.
FormData is not being constructed as you would expect. You can try this out by opening Chrome Devtools' Network tab and watch the request as it goes by: empty request payload.
The problem is that the FormData constructor's argument relies on each input in the form having a name attribute, which you're missing. If you add it, (name="name") your front end should behave as expected:
<input type="text" name="name" value={this.state.value} onChange={this.handleChange} />
EDIT: As per your above conversation, seems like you also have a server side CORS issue. My answer fixes your original question, but yes you'll need to resolve the CORS one as well, the easiest way probably being to refer to the docs of whatever Java framework you're using. It's a very common problem and should be in FAQ.

Post form without name preferably with JSoup

I am building an Android app and I want to post a html form that looks like this:
<form onsubmit="ShoutBox.postShout(); $('shout_data').value = ''; return false;">
Shout: <input type="text" id="shout_data" size="50"> -
<input type="submit" value="Shout Now!" id="shouting-status"></form>
I am using Jsoup in the rest of the application and I would preferably use it for this aswell.
I know about the .data(name, value) method, but since the html text and button don't have name attributes, that's not working. I can extract the field by using the ids and fill the field with: Element.val(String val); But I don't know how to post the form after that. Can anyone help me?
This is the JavaScript code for posting it:
postShout: function() {
message = $("shout_data").value;
if (message == "") {
return false;
}
$("shouting-status").value = ShoutBox.lang[0];
postData = "shout_data="+encodeURIComponent(message).replace(/\+/g, "%2B");
new Ajax.Request('xmlhttp.php?action=add_shout', {method: 'post', postBody: postData, onComplete: function(request) { ShoutBox.postedShout(request); }});
},
The post is not done via a form submit and post variables but via JavaScript and an XML HTTP request. JSoup is incapable to execute JavaScript. You need a browser that you can remote control. To do this headless in Java HTMLUnit is a good choice.

How to send values of the select box to servlet using ajax or jquery?

Im new to ajax. I want to redirect to servlet with the parameter value of the select box to my servlet. This is my code and its not retrieving values when I use request.getParameter("type") it gives me a null.
<script>
$(document).ready(function() {
$('#type').change(function() {
$.get('pickasset', function(responseJson) {
var type = $('#type').val();
$.ajax({
type:'POST',
url: 'PickAssetServlet',
data: type
});
});
});
});
</script>
<form action="pickasset" method="post">
<select id="type" name="type">
<option value="Non-Sap">Non Sap</option>
<option value="Sap">Sap</option>
</select>
</form>
When i change the select box, it must go to servlet and do logic there.
send your data like this-
data: { type : type }
If you're not getting the selected option from the select field, you need to use
$('#type').find(":selected").text() to retrieve the selected option. val() doesn't work with select fields. Also do what pXL said because that's how you send data with jQuery ajax methods
Check box value must be obtained from checkbox in the right way, as mentioned in jQuery docs (http://api.jquery.com/val/), just pay attention to multiple select, you're gonna have an array of values. You are doing it right, according to docs.
var varValue = var type = $('#type').val();
Then sending data as 'json' you will be able to read them with request.getParameter('type')
data: { "type" : varValue }
If you still get null, try to check if your "type" param and his value are in the request (chrome request inspector will be usefull, then check it in the debugger).
.
P.S.
Just check if you have something in your webapp filterchain that may wrap you request or hide some params, in some large web-app you get lost very easly.

Calling a backend Java method from JavaScript/jQuery in JSP

I have a JSP in which there is a select list containing entity kind names. When I select an entity kind I need to populate another select list with the field names of the selected entity kind. For that I call a JavaScript function on the onchange event.
In the JavaScript method I need to call a method in the backend that returns an arraylist that contains the field names of the selected entity kind.
How do I call the method with and without Ajax? Also how do I populate the second select list dynamically with the arrayList?
I'll describe two ways to go: with/without AJAX.
If you want to do a synchronous form submit you'll need to attach onchange event to your first select element:
<select name="select-one" id="select-one" onchange="this.form.submit()">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
When done this way, the form will be submitted and first select option will be available as request.getParameter("select-one"), based on which you'll provide data for second dropdown population, typically forwarding to a JSP.
If you want to retrieve a list via AJAX and repopulate another dropdown, you can send an AJAX request and handle returned data in a callback function:
var val = $('#select-one option:selected').val();
$.ajax({
url: "servletURL",//servlet URL that gets first option as parameter and returns JSON of to-be-populated options
type: "POST",//request type, can be GET
cache: false,//do not cache returned data
data: {one : val},//data to be sent to the server
dataType: "json"//type of data returned
}).done(function(data) {
var second = $("#select-two");
$.each(data, function() {
options.append($("<option />").val(this.value).text(this.label));
});
});
When done this way, the second dropdown will be repopulated without page refresh.
Write a JavaScript function names callAJAX on the onchage event of your select drop down
In your callAJAX function , make an ajax call to the back end, get the response from the server, and populate the new drop down with the response coming in your ajax call
I hope you can make ajax calls , if not let me know.
You want to load your list dynamically from backend. You must communicate with your server either:
with a page load (form submit)
or without a page load(ajax).
If AJAX is not your requirement, I suggest you do it by form submit(with page load) first because it's simple and easier for beginner.
Agree with Jai. You will have to submit that form to the java method, then your java method will return the arrayList. Of course if you form submit, your page will be refreshed and I'm not sure if your previously selected values will still be selected on the form. I'm not too clued up with this method of doing it. I prefer to use jquery.
With jquery you can do it like this:
$.ajax({
url: "/MyApp/MyClass/getArrayList",
type: "GET",
data: "selectedEntity=" + s_entity,
success: function(response){
//handle returned arrayList
},
error: function(e){
//handle error
}
});
Put this in a function. Pass your selected entity as a parameter and handle the response in the success part. Of course your java method should map 'selectedEntity' to a parameter in the method header. In Spring it's done like this:
private #ResponseBody ArrayList getArrayList(#RequestParam("selectedEntity") String entity)

Ajax JQuery to Spring #RequestBody? How do I pass data?

Ajax JQuery to Spring #RequestBody? How do I pass data? I being doing spring for sometime now with passing form fields but I am working on a new system and we would like to use Ajax and RESTful to pass data. My controller looks like the sample one below but can someone please me with the ajax call to post it?? how do I post to the Spring controller and put the data in the body
#RequestMapping(method=RequestMethod.PUT, value="/employee/{id}")
public ModelAndView updateEmployee(#RequestBody String body) {
Source source = new StreamSource(new StringReader(body));
Employee e = (Employee) jaxb2Mashaller.unmarshal(source);
employeeDS.update(e);
return new ModelAndView(XML_VIEW_NAME, "object", e);
}
When using REST, it's important to understand the distinction between the different HTTP methods. PUT generally means that you're going to create a new collection or replace an existing one. POST generally means that you're adding a record to a collection. The main difference between the two is that PUT is idempotent, which means that repeating the same operation repeatedly doesn't change the state of the server.
In your code below, you're method is called "updateEmployee", which implies you're replacing a collection with a new one. Thus, PUT is the most appropriate HTTP Method to use in this scenario. However, you have a bug in your code. You didn't define the "id" in the parameter list:
// Added String id as a PathVariable
#RequestMapping(method=RequestMethod.PUT, value="/employee/{id}")
public ModelAndView updateEmployee(#RequestBody String body, #PathVariable String id) {
// You really don't need to do this. The Spring Framework can deserialize
// objects for you. However, one issue at a time ;)
// also, changed e to "employee" so the variable has a better name.
Source source = new StreamSource(new StringReader(body));
Employee employee = (Employee) jaxb2Mashaller.unmarshal(source);
employeeDS.update(employee);
return new ModelAndView(XML_VIEW_NAME, "object", employee);
}
To make the request to the server, use jQuery AJAX:
$.ajax({
url: "/employee/2?t="+new Date().getTime(),
contentType: 'application/x-www-form-urlencoded',
type: "PUT",
data: dataString,
context: document.body,
success: function(e){
alert(e);
},
error: function(jqXHR, textStatus, errorThrown) {
alert(" + textStatus + " : " + errorThrown);
}
});
dataString is a string representation of your data. You can either serialize the form, use JSON, or send a url-encoded form. Without seeing more code and more error messages in your question, it's unclear how you're representing your data when attempting to send it to the server. If you start here and fix the above errors in your Java code, this should get you past this specific error.
Another way to submit data to your REST method, just for testing, is to use a standard form, but use method="PUT", since that's what you're using in Spring:
<form name="test" action="/employee/2" method="PUT">
<input type="text" name="firstname" />
<input type="text" name="lastname" />
<input type="submit" name="submit" value="submit" />
</form>
This will use application/x-www-form-urlencoded. If you're unable to deserialize that, then try using JSON instead. Good luck!
Hope gives you a start!
$.ajax({
contentType : "application/json",
dataType : 'json',
type : "PUT",
url : targetUrl,
data : $(this).serializeObject(), //json serialization (like array.serializeArray() etc)
async : false,
success : function(data) {
// response
},
error : function(request, status, error) {
// any errors
}
});

Categories

Resources