How to call #RequestMapping method of Controller having specified URL using AJAX - ajax

I'm very new to Spring and Portlet. I want to use jqgrid to show some list. I am trying to call a method in controller which is annoted with the #RequestMapping but the method is not being called
My Controller has following method
#Controller(value = "myController")
public class MyController {
#RequestMapping(value="/myURL",method=RequestMethod.GET)
public #ResponseBody MyDTO initItemSearchGrid(RenderResponse response, RenderRequest request){
MyDTO myDto=new MyDTO();
return myDto;
}
}
My JSP code using AJAX
var urlink="/myURL"; /* myURL is the exact String written in value Attribute of
resourceMapping in Controller*/
$.ajax({
url :urlink,
cache: false,
data:$('#myForm').formSerialize(),
dataType: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(jsondata){
...
}
});
When above AJAX code is executing my method is not called.

You mention Portlets in your question. Working with Spring and portlets is a bit different from servlets.
So, assuming you have a portlet like this
#Controller
#RequestMapping("VIEW") // VIEW mapping (as opposed to EDIT)
public class MyPortlet {
#RenderMapping
public ModelAndView handleRenderView(RenderRequest request, RenderResponse response) {
ResourceURL resourceUrl = response.createResourceURL();
resourceUrl.setResourceID("myResource"); // this is the id used to reference a #ResourceMapping
ModelAndView ret = new ModelAndView("myPortlet");
ret.addObject("resourceUrl", resourceUrl.toString());
return ret;
}
#ResourceMapping("myResource")
public void handleMyResource(ResourceRequest request, ResourceResponse response) {
OutputStream out = response.getPortletOutputStream();
// write whatever to output
}
}
As you can see, the #ResourceMapping is identified by a resource ID. The url for the resource mapping can be created using the standard portlet API methods and classes createResourceURL() and javax.portlet.ResourceURL.
If you prefer to use the portlet taglibrary instead, you can also generate a resource URL using the <portlet:resourceRequest> tag.
Your view might look something like this
myPortlet.jsp
...
<script>
$.ajax({
url :${resourceUrl},
cache: false,
data:$('#myForm').formSerialize(),
dataType: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(jsondata){
.........
.........
.........
}
});
</script>
...

Related

Spring Boot: Ambiguous handler methods mapped for HTTP path 'http://localhost:8080/error'

Everytime I used ajax for posting, I'm getting this error but the passing of data works successfully. Some said that it is because of my return statement. I also don't have any mapping for /error. This is one of my work that causes this error.
AJAX:
$.ajax
({
type: 'post',
url: '/SaveDependent',
data:
{
dependent_id: 0,
reference_no: referenceNo,
dependent_name: dNameValue[i],
dependent_dob: dDobValue[i],
dependent_gender: dGenderValue[i],
dependent_occupation: dOccupationValue[i],
dependent_relationship: dRelationshipValue[i],
dependent_beneficiary: dBeneficiaryValue[i]
},
success: function (response)
{
alert("success");
},
});
CONTROLLER:
#RequestMapping(value= "/SaveDependent", method=RequestMethod.POST)
public String saveDependent(ClientApplicationDependent clientApplicationDependent) {
clientApplicationDependentService.saveOrUpdate(clientApplicationDependent);
return "success";
}
SERVICE:
public interface ClientApplicationDependentService {
public void saveOrUpdate(ClientApplicationDependent clientApplicationDependent);
}
SERVICE IMPL:
#Override
public void saveOrUpdate(ClientApplicationDependent clientApplicationDependent) {
clientApplicationDependentRepository.save(clientApplicationDependent);
}

Storing an image using ajax request inside Postgresql in Spring application

I am trying to store an image in postgresql db from my spring application but I am stuck with multiple problems and confusion.
First let me give you the overview of my spring application code:
var documentData = new FormData();
function update(){
var fname=document.getElementById("fname").value;
var lname=document.getElementById("lname").value;
var password=document.getElementById("password").value.trim();
var email=document.getElementById("email").value;
documentData.append('fname',fname);
documentData.append('lname',lname);
documentData.append('password',password);
documentData.append('email',email);
documentData.append('profilePic',$('#profilePic').attr('src'));
alert($('#profilePic').attr('src'));
$
.ajax({
type : 'PUT',
url : baseUrl + "/restApi/UpdateUser",
data : JSON
.stringify({
documentData
}),
success: function(){
location.reload(true);
},
error : function(e) {
},
dataType : "json",
contentType : "application/json"
});
}
}
$(function () {
$(":file").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
});
});
function imageIsLoaded(e) {
$('#profilePic').attr('src', e.target.result);
$('#viewPic').attr('src',e.target.result);
};
I have this controller
#RequestMapping(value = "/restApi/UpdateUser", method = RequestMethod.PUT, headers = "Accept=application/json")
public ServiceResponse modifyUser(#RequestBody Object user)
{
return setDataPut("http://localhost:7020/UpdateUser",user,getUserObject().getUsername(),getUserObject().getPassword());
}
In my setDataPut method I am sending response with GSON
WebResource webResource = client
.resource(path);
ClientResponse response = webResource.type("application/json").accept("application/json")
.put(ClientResponse.class, gson.toJson(object));
In model class I took byte[] type variable and in db I made column with type bytea
Now In above gson service the call is made to rest services hosted.
#CrossOrigin
#RequestMapping(value = "/ModifyUser", method = RequestMethod.PUT, headers = "Accept=application/json")
public ServiceResponse modifyUser(#RequestBody User user) {
/*Code which deals with storing User data*/
}
So I have taken all data through model User class.
Now earlier it was working perfectly until I wanted to store image also.
Nothing is getting saved no error.
Confusion: If I am sending image with some data then should I change content type or add enctype as "multipart/form-data". But If I use multipart then what should be changed in headers. Like #produces #consumes. Major doubt is whether I need to convert the image in binary code before sending?
Problem: I am having trouble in storing image in postgresql through ajax request. Please look through my code what is the problem.
You are asking quite a lot in one question here. Essentially, you are asking how to upload files from the browser/client to the Spring-based server, how to handle that upload in the Spring-based server in order to save it into a Postgresql database and associate it with my User entity so that I can fetch it again later.
So, let's have a go at answering all of that for you.
Let's start on the client-side. This code will upload the chosen file to an existing resource:-
index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script>
function upload() {
var data = new FormData();
data.append('file', jQuery('#file')[0].files[0]);
jQuery.ajax({
url: '/userImage/userId',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
});
}
</script>
</head>
<body>
<div>
<h1>New File</h1>
<input type="file" id="file" name="file"/>
<button onclick="upload()">Upload</button>
</div>
</body>
</html>
Now, turning our attention to the Spring-bsed server side. To abstract away the implementation of exactly how to store the uploaded file in the database (and how to update it, and how to fetch it, and how to delete it and so on) I would use Spring Content otherwise you have a lot of code to write that Spring Content already implements for you.
So, add the following dependencies:
pom.xml
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-jpa</artifactId>
<version>0.1.0</version> // 0.0.11 for Spring Boot 1 dependencies
</dependency>
Configure the database schema creation in one of your config classes:
Config.java
#Configuration
#EnableJpaStores // enable JPA-based storage
public class PostgresqlTestConfig {
...dataSource and entityManager, etc beans...
#Value("/org/springframework/content/jpa/schema-drop-postgresql.sql")
private Resource dropReopsitoryTables;
#Value("/org/springframework/content/jpa/schema-postgresql.sql")
private Resource dataReopsitorySchema;
#Bean
DataSourceInitializer datasourceInitializer() {
ResourceDatabasePopulator databasePopulator =
new ResourceDatabasePopulator();
databasePopulator.addScript(dropReopsitoryTables);
databasePopulator.addScript(dataReopsitorySchema);
databasePopulator.setIgnoreFailedDrops(true);
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource());
initializer.setDatabasePopulator(databasePopulator);
return initializer;
}
}
Associate content with your User entity:
User.java
#Entity
public class User {
...existing fields...
#ContentId private String contentId;
private String mimeType;
}
Create a UserStore:
UserImageStore.java
public interface UserImageStore extends AssociativeStore<User, String> {
}
Update your controller to handle the upload of files, store them in the database and associating that stored image on your entity:
UserController.java
#Autowired
private UserImageStore store;
...
#RequestMapping(value="/userImage/{userId}", method = RequestMethod.POST)
public ResponseEntity<?> setContent(#PathVariable("userId") Long id, #RequestParam("file") MultipartFile file)
throws IOException {
User user = // fetch your existing user here
user.setMimeType(file.getContentType());
String originalFilename = file.getOriginalFilename();
InputStream is = file.getInputStream();
OutputStream os = ((WritableResource)store.getResource(originalFilename)).getOutputStream();
IOUtils.copyLarge(is, os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
// associate content (this will update the #ContentId field)
store.associate(user, originalFilename);
// save updated content-related info
save(user);
return new ResponseEntity<Object>(HttpStatus.OK);
}
return null;
#RequestMapping(value="/userImage/{userId}", method = RequestMethod.GET)
public ResponseEntity<?> getContent(#PathVariable("userId") Long id) {
User user = // fetch your existing user here
Resource r = store.getResource(user.getContentId());
HttpHeaders headers = new HttpHeaders();
headers.setContentLength(r.getContentLength());
headers.set("Content-Type", user.getMimeType());
return new ResponseEntity<Object>(r, headers, HttpStatus.OK);
}
return null;
}
That's about it. So what's going to happen here is that when your app starts it sees the dependency on spring-content-jpa and then it sees your UserImageStore. Assumes that you want to store images (BLOBs) in jpa and injects a JPA implementation of the UserImageStore interface meaning that you don't need to write it yourself. Spring Content hides the implementation but exposes a relatively simply interface (based on Spring Resource actually) that is #Autowired into your controller making that implementation simple.
Anyways, let me know if you are using Spring Data or Spring Boot and I can update this answer so that it is more relevant for you.
HTH

Spring MVC Ajax form properties name

I have a form with a list of fields:
type, name, description, height ,width
I send by ajax to my controller, my controller receive this ajax call but he said that all input fields are null.
My mapped DTO have the same fields but with distinct name, really I don't need use the same name in my call ajax that in my #RequestBody dto class.
Its possible? I am limited to use same names in the class and the ajax calls?
This aren't a problem really, but I can't found any info about this.
My DTO properties:
ResourceCreateDTO [resourceTypeId=null, resourceId=null,
resourceName=null, resourceDescription=null, folderId=null]
My JSON data:
resource-description: "asdfasdfasdfasdfsadfasdfsdfasdfasdfasdfasdfsadfasdfasdf"
resource-folder: "0"
resource-folder-type: "1000"
resource-id: "1006"
resource-name: "asdfasdfasdfasdf"
My AJAX Call:
$("#createModalSubmit").click(function(){
var data = {};
$('#createForm *').filter(':input').each(function(){
var input = $(this);
data[input.attr("name")] = input.val();
delete data["undefined"];
});
$.ajax({
contentType : "application/json; charset=utf-8",
type: "POST",
url: context + "/editor/create",
data: JSON.stringify(data),
dataType : 'json',
cache: false,
success:function(result){
},
error:function(){
}
});
});
My Controller config:
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public #ResponseBody ResourceDTO create(#RequestBody ResourceCreateDTO dto)
throws Exception {
System.out.println("dto: " + dto.toString());
This system out prints the above DTO toString.
I am searching any type of anotation or config that I can name the DTO properties:
#MyCustomName("resource-name")
private String resourceName;
Use my "resource-name" from the AJAX call.
If your DTO cannot have the same name that is being used in your ajax, you can then match it manually inside your controller.
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public #ResponseBody ResourceDTO create(#RequestBody String dto)
throws Exception {
//mapping
}
Or
#RequestMapping(value = "/editor/create", method = RequestMethod.POST)
public #ResponseBody ResourceDTO create(#RequestBody Map<String,Object> dto)
throws Exception {
//mapping
}

AJAX returns 404 in Spring MVC

ViewResolver (my jsp is in the right folder as specified on prefix value):
<!-- Resolves views selected for rendering by #Controllers -->
<!-- to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
Servlet mapping:
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>*.fst</url-pattern>
</servlet-mapping>
Controller:
#Controller
public class HomeController {
private static final Logger logger =
LoggerFactory.getLogger(HomeController.class);
#RequestMapping("/home")
public ModelAndView home(String user, HttpServletRequest request) {
logger.info("Home controller has been executed");
ModelAndView mv = new ModelAndView();
mv.addObject("userName", user);
mv.addObject("controllerName", request.getRequestURI());
mv.setViewName("home");
return mv;
}
#RequestMapping(value = "/testAjax", method = RequestMethod.POST)
public String testAjax(#RequestParam("memberId") String id,
HttpServletRequest request, HttpServletResponse response,
Locale locale, Model model) {
logger.info("Text Ajax action has been executed. My Parameter is " + id);
return id;
}
}
After turning on Tomcat 8 server on STS IDE, accessing this web with this url http://localhost:8080/home.fst works okay.
But on the page, calling AJAX like below throws a 404 error:
$.ajax({
type: "POST",
url: "/testAjax.fst",
data: {"memberId" : "test"},
success: function (result) {
console.log(result)
}
});
This is console error log:
POST http://localhost:8080/testAjax.fst 404 (Not Found)
k.cors.a.crossDomain.send jquery-2.1.3.min.js:4
n.extend.ajaxhome.fst:11 (anonymous function) jquery-2.1.3.min.js:3
n.event.dispatch jquery-2.1.3.min.js:3
r.handle
Strange thing is that it calls testAjax controller just fine and there's no error log on server.
logger.info("Text Ajax action has been executed. My Parameter is " + id);
When textAjax action is invoked by my AJAX, the log is printed as well. I checked it out with debug point too (it broke alright).
What seems to be the matter??
Everything's good just Add #ResponseBody annotation in your method and also I suggest you to change your request method POST to GET
Spring
#RequestMapping(value = "/testAjax", method = RequestMethod.GET) //Made Change
#ResponseBody //added
public String testAjax(#RequestParam("memberId") String id, HttpServletRequest request, HttpServletResponse response, Locale locale, Model model) {
logger.info("Text Ajax action has been executed. My Parameter is " + id);
return id;
}
JQuery
$.ajax({
type: "GET", //Made Change
url:"/testAjax.fst",
data: {"memberId" : "test"},
success: function (result) {
console.log(result)
}
});

Spring Controller + Ajax return String

I want to return String from Spring MVC Controller to Ajax.
It is not working as expected and gives error.
My Ajax codes for this:
function ajaxRequest(item) {
$.ajax({
type: "POST",
url: "/myPage",
data: {
item: item
},
success: function (html) {
alert(html);
},
error: function(e) {
console.log("Error:" + e);
}
});
}
My Controller:
#RequestMapping(value = "/myPage", method= RequestMethod.POST, produces="text/plain")
public #ResponseBody String myController(HttpServletRequest request) {
String myItem = request.getParameter("item");
...
return myItem + "bla bla bla";
}
Chrome console result:
POST http://localhost:8080/myPage 406 (Not Acceptable) jquery.js
Error:[object XMLHttpRequest]
What am i missing here?
When you return a String from a handler method annotated with #ResponseBody, Spring will use a StringHttpMessageConverter which sets the return content-type to text/plain. However, your request does not have an Accept header for that content-type so the Server (your Spring app) deems it unacceptable to return text/plain.
Change your ajax to add the Accept header for text/plain.
I have solved it. We can return correct values with response writer.
#RequestMapping(value = "/myPage")
public void myController(HttpServletRequest request, HttpServletResponse response) throws IOException {
String myItem = request.getParameter("item");
...
response.getWriter().println(myItem + "bla bla bla");
}
Be sure that you have Jackson dependency. Spring MVC can relies on it.

Resources