I'm creating an AJAX call that would pass the parameters to the Servlet. However my value displays "null" after debugging. Are both my AJAX and Java Servlet code has missing implementations?
Below is my AJAX implementation :
function getImageDataResponse() {
var isSuccess = false;
var queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const pagePath = urlParams.get('item');
$.ajax({
type: 'POST',
url: '/bin/servlet-demo-path',
data: {urlParams : pagePath},
contentType: 'application/json',
async : false,
success: function (data) {
if(data.imagePath !== null) {
isSuccess = true;
}
},
error: function (error) {
}
});
return isSuccess;
}
This is my Java Servlet implementation:
#Component(service = Servlet.class, property = {
Constants.SERVICE_DESCRIPTION + "=Registered By Path Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.paths="+ "/bin/servlet-demo-path"})
public class ImageServlet extends SlingAllMethodsServlet {
#Override
protected void doPost(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
String urlPath = req.getParameter("urlParams");
PageManager pM = req.getResource().getResourceResolver().adaptTo(PageManager.class);
Page specificPage = pM.getPage(urlPath);
ValueMap imageMap = specificPage.getProperties("image");
resp.setContentType("application/json");
}
}
Related
ERROR:
The resource identified by this request is only capable of generating
responses with characteristics not acceptable according to the request
"accept" headers.
Here is my Ajax code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
/* function new_element(){ */
$(document).ready(function(){
$("#search").click(function(){
console.log("fetched list");
$.ajax({
url: "http://localhost:8080/SpringMvcJdbcTemplate/listContact",
type : "GET",
dataType : 'json',
/* contentType : "application/json", */
accept : "application/json",
success : function(data) {
alert(this.getResponseHeader("Content-Type"));
console.log("SUCCESS: ", data);
display(data);
},
error : function(e) {
console.log("ERROR: ", e);
display(e);
}
});
});
});
function display(data) {
console.log("inside func list");
var json = "<h4>Ajax Response</h4><pre>"
+ JSON.stringify(data, null, 4) + "</pre>";
$('#feedback').html(json);
}
</script>
The controller class
#JsonView(Views.Public.class)
#RequestMapping(value = "/listContact",
method = RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public AjaxResponseBody listContact(ModelAndView model) throws IOException {
List<Contact> listContact = contactDAO.list();
System.out.println("listContact");
List<Contactdup> listContdup = new ArrayList<Contactdup>();
Contactdup contactdup = null ;
AjaxResponseBody result = new AjaxResponseBody();
for(Contact contact:listContact) {
contactdup = new Contactdup();
contactdup.setFname(contact.getFname());
System.out.println("inside for");
System.out.println(contact.getFname());
listContdup.add(contactdup);
}
result.setResult(listContdup);
result.setCode("200");
result.setMsg("");
return result;
}
AjaxResponseBody:
package ajaxrespose;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonView;
import net.codejava.spring.model.Contactdup;
import net.codejava.spring.model.Views;
public class AjaxResponseBody {
public List<Contactdup> getResult() {
return result;
}
public void setResult(List<Contactdup> result) {
this.result = result;
}
#JsonView(Views.Public.class)
String msg;
#JsonView(Views.Public.class)
String code;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#JsonView(Views.Public.class)
List<Contactdup> result;
}
The route you are calling is probably not returning content-type "application/json".
This is web code:
DecoupledEditor
.create( document.querySelector( '#webDetails' ),{
language: 'zh-cn',
image: {
toolbar: [ 'imageTextAlternative' ],
styles: [ 'full', 'side' ]
},
ckfinder: {
uploadUrl: '<%=WEBPATH%>/platform/updateMaterial'
}
} )
.then( editor => {
const toolbarContainer = document.querySelector( '#toolbar-webDetails' );
toolbarContainer.appendChild( editor.ui.view.toolbar.element );
} )
This is Spring controller:
#PostMapping("updateMaterial")
#ResponseBody
public String updateMaterial(#RequestParam("upload") MultipartFile file, HttpServletRequest request){
String trueFileName = null;
String realPath = null;
try {
realPath = request.getSession().getServletContext().getRealPath("/upload");
System.out.println(realPath);
trueFileName = uploadImg(realPath, file);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return "{\"default\":\"" + realPath + File.separator + trueFileName + "\"}";
}
Here I return the address of the image on disk.
It is json String style. I want CKEditor 5 api to return the information, but still failure.
What do I need to return in the background to succeed, or am I missing the step?
thank you.
There are many people asking this question, but none of them have a clear solution. Finally, I found it. My code is as follows.
class UploadAdapter {
constructor(loader) {
this.loader = loader;
}
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('upload', this.loader.file);
data.append('allowSize', 10);//允许图片上传的大小/兆
$.ajax({
url: 'loadImage',
type: 'POST',
data: data,
dataType: 'json',
processData: false,
contentType: false,
success: function (data) {
if (data.res) {
resolve({
default: data.url
});
} else {
reject(data.msg);
}
}
});
});
}
abort() {
}
}
DecoupledEditor
.create( document.querySelector( '#b' ), {
language:"zh-cn"
})
.then( editor => {
const toolbarContainer = document.querySelector( '#a' );
toolbarContainer.appendChild( editor.ui.view.toolbar.element );
// This place loads the adapter.
editor.plugins.get('FileRepository').createUploadAdapter = (loader)=>{
return new UploadAdapter(loader);
};
} )
.catch( error => {
console.error( error );
} );
I am new to angular .. I hava java rest api which return CSV file in response as attachment as | "Content-Disposition", "attachment; filename=" | content-type :application/octet-stream
Now when i am calling this api from AngularJS using $http i am getting response.data ="" (blank)
I am using basic authorisation for security so I have to pass Header while calling calling API so can't use link click or new window open fro CSV download.
to test when i removed authorisation and hit the url in browser then CSV file is being downloaded.so no issue at server side .
I need help at angularjs side to download CSV file from web api response as attachment.
Here is my Java API Code
public class ServiceAPI {
#GET
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFileAsCSVFile(){
byte[] file=null;
try {
ArrayList<> List=new ArrayList<>();// data retrieved from DB
if(null != List){
file=convertJsonToCSV(new Gson().toJson(List));
}
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Response.ok(getBytes(file),MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=" + "FileName.csv").build();
}
}
and Angular code :
app.controller('review', ['$scope', '$http', function ($scope, $http){
$scope.fromDate = new Date();
$scope.toDate = new Date();
$scope.minDate = new Date(
$scope.fromDate.getFullYear(),
$scope.fromDate.getMonth() - 2,
$scope.fromDate.getDate(),
$scope.toDate.getFullYear(),
$scope.toDate.getMonth() - 2,
$scope.toDate.getDate()
);
$scope.maxDate = new Date(
$scope.fromDate.getFullYear(),
$scope.fromDate.getMonth() - 2,
$scope.fromDate.getDate(),
$scope.toDate.getFullYear(),
$scope.toDate.getMonth() - 2,
$scope.toDate.getDate()
);
$scope.reviews = json;
function openSaveAsDialog(filename, content, mediaType) {
var blob = new Blob([content], {type: mediaType});
saveAs(blob, filename);
}
function callApi(url) {
// var dat=apiFactory.getServiceData(url);
// console.log(dat);
// apiFactory.getServiceData(url);
var responseType='arraybuffer';
var expectedMediaType='application/octet-stream';
$http.get(url, {
headers: {
accept: expectedMediaType
},
responseType:responseType,
cache: true,
transformResponse: function (data) {
var pdf;
if (data) {
pdf = new Blob([data], {
type: expectedMediaType
});
}
return {
response: pdf
};
}
}).then(function (data,status,headers) {
var filename='Preview.csv',
octetStreamMime = "application/octet-stream",
contentType;
headers = data.headers();
contentType = headers["content-type"] || octetStreamMime;
// openSaveAsDialog(filename, response.data, expectedMediaType);
if (navigator.msSaveBlob) {
var blob = new Blob([data], { type: contentType });
navigator.msSaveBlob(blob, filename);
} else {
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (urlCreator) {
// Try to use a download link
var link = document.createElement("a");
if ("download" in link) {
// Prepare a blob URL
var blob = new Blob([data.data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
// Simulate clicking the download link
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(event);
} else {
// Prepare a blob URL
// Use application/octet-stream when using window.location to force download
var blob = new Blob([data], { type: octetStreamMime });
var url = urlCreator.createObjectURL(blob);
$window.location = url;
}
}
}
});
};
$scope.submit = function (fromDate, toDate) {
$scope.url = API_url;
var resp =callApi(($scope.url).split(" ").join("%20"));
console.log(resp);
};
},
]);
I have an example with spring MVC instead of JAX-RS (Jersey)
HTML:
<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>
Angularjs controler:
$scope.downloadCsv = function () {
console.log("downloadCsv");
var fileName = "test.csv";
var a = document.createElement("a");
document.body.appendChild(a);
XxxxxxServiceCSV.downloadCsv().then(function (result) {
console.log("downloadCsv callback");
var file = new Blob([result.data], {type: 'application/csv'});
var fileURL = URL.createObjectURL(file);
a.href = fileURL;
a.download = fileName;
a.click();
});
};
Angularjs services:
angular.module('xxxxxxxxApp')
.factory('XxxxxxServiceCSV', function ($http) {
return {
downloadCsv: function () {
return $http.get('api/downloadCSV', { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
};
});
Java code JAX-RS(spring MVC):
#RequestMapping(value = "/downloadCSV", method = RequestMethod.GET, produces = "application/csv")
public void demo(HttpServletResponse response) throws IOException {
List<String> names = new ArrayList<String>();
names.add("First Name");
names.add("Second Name");
names.add("Third Name");
names.add("Fourth Name");
BufferedWriter writer = new BufferedWriter(response.getWriter());
try {
response.setHeader("Content-Disposition", "attachment; filename=\"test.csv\"");
for (String name : names) {
writer.write(name);
writer.write(",");
}
writer.newLine();
} catch (IOException ex) {
} finally {
writer.flush();
writer.close();
}
}
StudentController - here is my controller class that returns exceptions and i want to handle and display these in jsp
#RequestMapping(value = RequestURL.ADD_STUDENT, method = RequestMethod.POST)
#ResponseBody
public void addStudent(#RequestBody AddStudentRequest addStudentRequest) throws StudentGroupNumberNotFoundException, SpecializationNotFoundException {
User user = new User(addStudentRequest.getUsername(),
addStudentRequest.getPassword(), Role.ROLE_STUDENT);
userService.add(user);
user = userService.findByUsername(addStudentRequest.getUsername());
int userId = user.getId();
try {
int groupId = studentGroupService
.getIdByGroupNumber(addStudentRequest.getGroup());
int specializationId = specializationService
.getIdByName(addStudentRequest.getSpecialization());
Student student = new Student(userId, specializationId,
addStudentRequest.getName(),
addStudentRequest.getRegistrationNumber(), groupId,
addStudentRequest.getYear());
studentService.add(student);
} catch (StudentGroupNumberNotFoundException e) {
throw new StudentGroupNumberNotFoundException(e.getMessage());
} catch (SpecializationNotFoundException e) {
throw new SpecializationNotFoundException (e.getMessage());
}
}
student.jsp - jsp page for student
function addStudent() {
var username = $('#modalStudentUsername').val();
var password = $('#modalStudentPassword').val();
var name = $('#modalStudentName').val();
var registrationNumber = $('#modalStudentRegistrationNumber').val();
var group = $('#modalStudentGroup').val();
var year = $('#modalStudentYear').val();
var specialization = $('#modalStudentSpecializationId').val();
var data = '{ "username" : "' + username + '", "password": "'
+ password + '", "name":"' + name
+ '","registrationNumber": "' + registrationNumber + '" , "specialization": "' + specialization
+ '","group": "' + group+'", "year": " ' + year + '" }';
var token = $('#csrfToken').val();
var header = $('#csrfHeader').val();
$.ajax({
type : "POST",
url : "student/add",
contentType : 'application/json',
data : data,
beforeSend : function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader(header, token);
},
success : function(data, status, xhr) {
alert("Success!");
},
error : function(xhr, status, errorThrown) {
alert("Error!");
},
});
}
I want to display in the alert from ajax the exception's message from controller. Could anyone help me? Thanks!
Change the method return type from void to String & give a call to xhr.responseText in alert() just like below:-
Change In Controller:
#ResponseBody
public void addStudent(#RequestBody AddStudentRequest addStudentRequest) throws StudentGroupNumberNotFoundException, SpecializationNotFoundException {
// business logic
}
to
#ResponseBody
public String addStudent(#RequestBody AddStudentRequest addStudentRequest) throws StudentGroupNumberNotFoundException, SpecializationNotFoundException {
// business logic
}
Change In JavaScript:
function addStudent() {
// ...
$.ajax({
type : "POST",
url : "student/add",
contentType : 'application/json',
data : data,
beforeSend : function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader(header, token);
},
success : function(data, status, xhr) {
alert(xhr.responseText);
},
error : function(xhr, status, errorThrown) {
alert(xhr.responseText);
},
});
}
I have written some sort of code to send data from client to spring model. and want that json data should automatically fill the java class. but not able to do this.
Jquery looks like this
$('#login-form').submit(function(event){
var username = $('#id_username').val();
var password = $('#id_password').val();
alert(username + password)
var json = { "loginId" : username, "password" : password};
$.ajax({
type: "POST",
url: $("#login-form").attr("action"),
data: JSON.stringify(json),
beforeSend: function(xhr){
var mess = validateForm();
if(mess.length != 0){
$('#error-mes').show();
$('#error-mes').html(mess);
event.preventDefault();
return false;
}
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
return true;
},
success: function(response){
$('#error-mes').html(response);
$('#error-mes').show();
},
error: function(e){
alert('Error: ' + e);
}
});
event.preventDefault();
$('#userName').hide();
$('#spn_password').hide();
});
Spring code like this
#RequestMapping(value = "/signin", method = RequestMethod.POST )
public #ResponseBody String submitCustSignInForm(HttpServletRequest request, #ModelAttribute("model") Person model,
HttpSession sess) {
String response = "";
Person person = null;
if (sess.getAttribute("USER_INFO") == null) {
person = tsService.login(model);
if (person == null) {
response = "User name or password does not match.";
} else {
response = "success";
sess.setAttribute("USER_INFO", person);
}
}
return response;
}
Person model has same loginId and password attribute and setter and getter in class.
can some body tell me how can it achieved.