ajaxform not submit the value if attachment is not available - java

I am a beginner in Java and go to create one web application. I am submitting one form to controller using ajaxform. There are few elements and one of them is type=file.
my controller method is as following
#RequestMapping(value = { "/addReplies" }, method = {
org.springframework.web.bind.annotation.RequestMethod.POST,
org.springframework.web.bind.annotation.RequestMethod.GET } )
#ResponseBody
public Map<String,Object> addReplies(
#Valid #ModelAttribute("Replies") Replies replies,
BindingResult result, HttpServletRequest request,
HttpServletResponse response,Locale locale,Principal principal,
#RequestParam(value = "fileData2",required=false) CommonsMultipartFile fileData2[]) throws ServletException,
IOException {
//perform some opraton
}
this everything is work properly if there is attachment available in data otherwise it does not go into this method.
if I remove #RequestParam(value = "fileData2",required=false) CommonsMultipartFile fileData2[] this parameter from method then work well but by this way I cannot get the attachment.
please try to understand my question and as soon as give me all possible solution.
This method is working well if I am not using ajax and submit form with regul

i also do this
but my coding also working
do this solution
#RequestMapping(value="/saveUserTask", method=RequestMethod.POST)
#ResponseBody
public Map<String,String> saveUserTask(
#RequestParam( value = "title" , required = false) String title,
#RequestParam( value = "projectid" , required = false) int projectid,
#RequestParam( value = "mileid" , required = false,defaultValue ="-1") int mileid,
#RequestParam( value = "responsible" , required = false) int responsible[],
#RequestParam( value = "startDate" , required = false) Date startDate,
#RequestParam( value = "endDate" , required = false) Date endDate,
#RequestParam( value = "description" , required = false) String description,
#RequestParam( value = "priority" , required = false, defaultValue="1") int priority,
#RequestParam( value = "workHours" , required = false) int workHours,
#RequestParam(value = "attachment" , required = false) MultipartFile myFile,
HttpServletRequest request,Principal principal,RedirectAttributes redirectAttributes,Locale locale) throws ParseException, IOException{
String fileAttachPath;
if(myFile!=null)
fileAttachPath=request.getSession().getServletContext().getRealPath("/WEB-INF/attechments/"+ new Date().getTime() + "_" + myFile.getOriginalFilename());
else
fileAttachPath="";
}

For uploading a file normally you need to use encType="multipart/form-data" in your form. If you want to use Ajax to upload a file, Along with Simple ajax call you need to use its methods
or
whey you are uploading the file, before Serialize the ajaxForm first check is it filepart is null or not, if its null then disable the element for longer availability and submit
beforeSerialize: function($form, options){
//before serializing the data have to disable element if the data is not avaliable
$(".attachfile").filter(function(){
return !this.value; }).attr("disabled", "disabled");
},

I just did this:
$("#myform").bind('ajax:complete', function() {
// tasks to do with ajax submit
});
And things worked perfectly.
See this api documentation for more specific details.

have you try this before to submit ajax form data object?
#RequestMapping(value ="/settingsSim",method=RequestMethod.POST)
#ResponseBody
public Map uploadSimSettings(#RequestBody String body) {
/*
some controller logic
*/
}

Related

RestController method returned Content-Type = application/javascript in Spring 4.3, but application/json in Spring 5.6

I have this method:
#RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ValuesJsonObject getValuesAsJson(#RequestParam final String ownerId, #RequestParam final String searchString, #RequestParam final Long valueTypeId,
#RequestParam(required = false) final boolean extendedSearch, #RequestParam(required = false) final String meta3Filter,
#RequestParam(required = false) final String meta4Filter, #RequestParam(required = false) final String valueFilter,
#RequestParam(required = false) final String searchFields, #RequestParam(required = false) final Boolean distinct) {
//...Some Code
final ValuesJsonObject valuesObject = new ValuesJsonObject();
valuesObject.setValues(values);
return valuesObject;
}
This method is used to fetch data that is used for a GWT select box. The response normally looks something like this:
/**/gwt_jsonp.P0.onSuccess({"values":[{"denotation":"ZFO - Franconia","value":"ZFO - Franconia","description":null,"meta1":null,"meta3":null,"meta4":null}]});
It's some kind of GWT callback thing where JSON data is inside this Javascript function.
The response content-type was application/javascript in Spring 4.3 environment. Now, after the upgrade, the response-type is application/json. I tried to create a header and manually set up a ResponseEntity with a header that has Content-Type = "application/javascript" but still application/json is returned.
What I've tried so far:
Set #RequestMapping to #RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = "text/javascript) -> Response Content-Type in browser turns to text/html
Removed produces tag in RequestMapping entirely -> Response Content-Type in browser turns to application/xml;charset=UTF-8
Tried to manually set the Response headers like that, but that got me a 500 error:
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "text/javascript");
return new ResponseEntity<>(valuesObject, headers, HttpStatus.OK);
Edit: Some new findings! When I remove the data from the body and just ad null, then the content-type is set properly. If I have the data in the body, I receive a 500 error. It must have something to do with the payload (but it worked before the Spring update....).
What I then tried was to properly transform the payload into JSON data using ObjectMapper. The response data then looks like normal JSON and the content-type is correctly set to application/javascript:
Response:
{"values":[{"denotation":"ZFO - Franconia","value":"ZFO - Franconia","description":null,"meta1":null,"meta3":null,"meta4":null}]}
BUT the Javascript callback is missing in this response. Question is how to add this back again. I think that's a GWT issue...
I have a solution for my problem.
When we upgraded to Spring 5.6, Spring's AbstractJsonpResponseBodyAdvice was removed. I think this extension class was responsible for setting the correct content-type in our response and converting everything to JSONP. When the class was gone, the wrong content-type was set. So I had to manually set content-type to text/javascript in #RequestMapping, but I also had to provide it in the header of the response.
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "text/javascript");
I also had to capture the callback address of the JSONP / GWT call in a new parameter in method signature
#RequestMapping(value = "/getValuesAsJson", method = RequestMethod.GET, produces = "text/javascript")
public ResponseEntity getValuesAsJson(#RequestParam final String ownerId, #RequestParam final String searchString, #RequestParam final Long valueTypeId,
#RequestParam(required = false) final boolean extendedSearch, #RequestParam(required = false) final String meta3Filter,
#RequestParam(required = false) final String meta4Filter, #RequestParam(required = false) final String valueFilter,
#RequestParam(required = false) final String searchFields, #RequestParam(required = false) final Boolean distinct,
#RequestParam(required = true) final String callback) {
And finally I wrapped the Javascript method name around the JSON data:
return ResponseEntity.ok()
.headers(headers)
.body(callback + "(" + valuesObjectAsJson + ")");
This was basically the solution someone else here on SA proposed but I can't find the thread again.

GetMapping After Postmapping

I am trying a GetMapping After a PostMappng. Postmapping basically does an Update.
What I am doing is, if the condition satisfies then no need to update but simply redirect to another page. But seem it is not working, It seems a GetRequest is not Possible from a Postrequest but I have read articles and even seen solutions on Stack but dont know why dont they work for me. Any help or hint will be appreciated
#PostMapping(path = "/campaign/services/migrate")
public String migrateCampaigns(
#RequestParam(required = false, value = "campaignCount") int campaignCount,
#RequestParam(required = false, value = "client-email") String clientEmail,
#RequestParam(required = false, value = "campaign-id") List<String> campaignIds,
#RequestParam(required = false, value = "selectAllCampaigns") String selectAllCampaigns,
HttpServletRequest request,
HttpServletResponse httpResponse,
Model model) throws ServletException, IOException {
logger.info("Retrieving source and destination credential from cookies");
String url = null;
if(campaignCount >= 20) {
url = "redirect:/login/oauth/login-with-eloqua";
}
String adminsEmail = contactService.getEmail(siteNameForEmail);
String userEmail = cookieService.retrieveCookieValue(cookieDefinitionUserEmail);
String clientsEmailAddresses = adminsEmail + "," + userEmail;
migrateResponse = migrationService.migrate(campaignIds, request.getCookies(), clientsEmailAddresses);
}
//return migrateResponse;
return url;
}
#GetMapping(path = "/login/oauth/login-with-eloqua")
public String eloquaOauthLoginPage(HttpServletRequest request, Model model, HttpServletResponse response) {
return "login/oauth/login-with-eloqua";
}
There are many ways to get this approach, it's up on to you. I can see you have a class called HttpServletResponse, you can use a method that name isĀ of the class.
Example:
httpSrvltResponse.sendRedirect("/login/oauth/login-with-eloqua")`

How to send multipart form data with json value in Spring Boot

Hi there, I want to send to postman a body with json and an image in formd-data...
I save the form-data image in a s3 bucket, the entity has as an string attribute that is the link of the image
Here my spring boot controller
#PostMapping(consumes = { "multipart/mixed", "multipart/form-data" }, produces = MediaType.APPLICATION_JSON_VALUE)
public CharacterResponse createCharacter(#Valid #RequestBody CharacterRequest characterRequest, #RequestParam(value = "file", required = false) MultipartFile file) {
CharacterDto characterDto = mapper.map(characterRequest, CharacterDto.class);
CharacterDto createdCharacter = characterService.createCharacter(characterDto, file);
return mapper.map(createdCharacter, CharacterResponse.class);
}
I have already tried with #RequestParam and #RequestPart for the MultiPartFile...
I get this error:
"Content type 'multipart/form-data;boundary=--------------------------340232294957024834187036;charset=UTF-8' not supported"
From my point of view you could try this:
in method attributes use #RequestPart with values. And also you should use the same structure in your client (for ex. in postman for each part you should explicitly set content-type, auto content-type works not perfect. For keys you should use values from #RequestPart, and in values just put your payload)
#PostMapping(consumes={ MediaType.MULTIPART_FORM_DATA_VALUE },
produces=MediaType.APPLICATION_JSON_VALUE)
public CharacterResponse createCharacter(
#Valid #RequestPart("body") CharacterRequest characterRequest,
#RequestPart(value="file", required=false) MultipartFile file)
{
//code
}
Just using #RequestParam for both parameter should do the job.
#PostMapping("/api/path")
public CharacterResponse createCharacter(#Valid #RequestParam CharacterRequest characterRequest, #RequestParam(required = false) MultipartFile file) {
CharacterDto characterDto = mapper.map(characterRequest, CharacterDto.class);
CharacterDto createdCharacter = characterService.createCharacter(characterDto, file);
return mapper.map(createdCharacter, CharacterResponse.class);
}

redirect flash attribute not working for List<>

I would like to redirect a message list from a post to a get.
#RequestMapping(method = RequestMethod.GET, value = "/ManageNonRoutedActivities")
public ModelAndView manageNonRoutedActivities(ModelAndView modelAndView,
ArrayList<Message> messages,
#ModelAttribute("nonRoutedActivity") NonRoutedActivity nonRoutedActivity,
#RequestParam(value = "search", defaultValue = "") String search,
#RequestParam(value = "orderField", defaultValue = "Description") String orderByField,
#RequestParam(value = "orderDirection", defaultValue = "asc") String orderByDirection) {
ManageNonRoutedActivitiesRequest request = new ManageNonRoutedActivitiesRequest(new ManageNonRoutedActivitiesDAOImpl(), search, orderByField, orderByDirection);
System.out.println(messages.size());
modelAndView.setViewName("default");
modelAndView.addObject("viewModel", new ManageNonRoutedActivitiesImpl(request, search, orderByField, messages));
return modelAndView;
}
#RequestMapping(method = RequestMethod.POST, value = "/ManageNonRoutedActivities")
public String updateOrCreateActivity(#Valid NonRoutedActivity nonRoutedActivity,
BindingResult result,
RedirectAttributes redirectAttributes) {
SecurityAccessor securityAccessor = new SecurityAccessor();
ArrayList<Message> messages = new ArrayList<>();
if (result.hasErrors()) {
return manageErrorsForManageNonRoutedActivities(result, nonRoutedActivity, redirectAttributes, messages);
}
if (nonRoutedActivity.shouldUpdateEndDate()) {
nonRoutedActivity.updateEndDate();
messages.add(new Message("endDate.add.success", "success"));
} else
messages.add(new Message("activity.add.success", "success"));
nonRoutedActivity.setModifiedBy(securityAccessor.getLoggedInUsersName());
nonRoutedActivity.save();
redirectAttributes.addFlashAttribute("messages", messages);
return "redirect:/ManageNonRoutedActivities";
}
The problem I'm having is that messages in the get part of the controller keeps coming out null. I originally had this messages instance as a List<Message> but this did not work since messages can be null. This caused an issue since List cannot be instanciated. This is why I am using ArrayList. This is not working though because the ArrayList is not binding correctly. Anyone know why this is happening and how to resolve this issue without creating a wrapper for the list?
So I'm not sure this is the best solution but the if I remove the name of the redirect attribute it works.

Catch GET request parameters in a Map<String,String>

I'm trying to catch key value pairs in a Map parameter at spring MVC side. This looks to me to be something simple but I can't wrap my head around it at the moment. Take following url
www.goudengids.be.localhost:8080/ms/view/sendContactForm.ajah?pageId=711408&listingId=685592&siteId=353009&url=http%3A%2F%2Fwww.goudengids.be.localhost%3A8080%2Fms%2Fms%2Fkbc-bank-versicherung-recht-4780%2Fms-353009-preview%2F&moduleId=65920100&mySiteId=353009&pageShortId=1&prefills[Naam]=janneke
You'll notice at the end my latest attempt to get this working prefills[Naam]=janneke. I like to catch this in the following controller.
public String getContactForm(#RequestParam(required = true) Long moduleId, #RequestParam(required = true) String url, #RequestParam(required=false) Map<String,String> prefills, Long mySiteId, Integer pageShortId,
DefaultPageParameters defaultPageParameters, ModelMap model, HttpServletRequest request, HttpServletResponse response, Locale locale) throws Exception {
However I'm recieving all parameters in the request in my prefills variable instead of just Naam,janneke. Is this even possible what I'm attempting or should I go with a large string with a token to tokenize ?
prefills=naam:janneke|title:maan|subject:space
I couldn't find a clean way out, so I went for the pragmatic solution
public String getContactForm(#RequestParam(required = true) Long moduleId, #RequestParam(required = true) String url, #RequestParam(required=false) List<String> prefills, Long mySiteId, Integer pageShortId,
DefaultPageParameters defaultPageParameters, ModelMap model, HttpServletRequest request, HttpServletResponse response, Locale locale) throws Exception {
private void prefillFieldsWithData(List<String> prefills, ModelMap model, BasicContactFormVo contactFormVo) {
if(prefills != null && !prefills.isEmpty()){
Map<String, String> valuesOfCustomFields = new HashMap<String, String>();
List<ContactFormElementVo> customFormElements = contactFormVo.getCustomFormElements();
for (String prefillData : prefills) {
if(prefillData.contains("|")){
String[] prefillFieldData = prefillData.split("|");
for (ContactFormElementVo contactFormElementVo : customFormElements) {
if(contactFormElementVo.getLabel().equals(prefillFieldData[0])){
valuesOfCustomFields.put("cfe"+contactFormElementVo.getId().toString(), prefillFieldData[1]);
break;
}
}
}
}
model.addAttribute("customFieldValues",valuesOfCustomFields);
}
}
It's a bit sad I have to do it this way, but it seems Spring has a generic way of detecting a Map as request parameter and filling it with all parameters in the request. There is no way around that except overloading that class which I rather do not considering it's part of the entire MVC mechanic.
I call the controller now with following URL. It works just ... meh ... not my favorite solution
http://www.goudengids.be.localhost:8080/ms/view/sendContactForm.ajah?pageId=711408&listingId=685592&siteId=353009&url=http%3A%2F%2Fwww.goudengids.be.localhost%3A8080%2Fms%2Fms%2Fkbc-bank-versicherung-recht-4780%2Fms-353009-preview%2F&moduleId=65920100&mySiteId=353009&pageShortId=1&prefills=Naam|janneke%20zag%20eens%20pruimen&prefills=E-mail|maan

Categories

Resources