simple AJAX JQuery example gives me 500 internal server error - java

hi i'm working in a spring mvc project and i'm getting this error when i hit the button in my form
500 (Internal Server Error) jquery.min.js:6
x.ajaxTransport.x.support.cors.e.crossDomain.send jquery.min.js:6
x.extend.ajax AddUser:19
doAjaxPost AddUser:41
onclick
i'm trying to do a simple AJAX JQuery example that adds users to a list but i get that error when i press the add button in my form
this is my controller class:
#Controller
public class UserListController {
private List<User> userList = new ArrayList<User>();
#RequestMapping(value="AddUser",method=RequestMethod.GET)
public String showForm(){
return "AddUser";
}
#RequestMapping(value="AddUser",method=RequestMethod.POST)
public #ResponseBody String addUser(#ModelAttribute(value="user") User user, BindingResult result )
{
String returnText;
if(!result.hasErrors())
{
userList.add(user);
returnText = "User has been added to the list. Total number of users are " + userList.size();
}
else
{
returnText = "Sorry, an error has occur. User has not been added to list.";
}
return returnText;
}
#RequestMapping(value="ShowUsers")
public String showUsers(ModelMap model)
{
model.addAttribute("Users", userList);
return "ShowUsers";
}
}
and this is my AddUser.jsp page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Add Users using ajax</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<!-- <script src="resources/js/libs/jquery-2.0.2.min.js"></script> -->
<script type="text/javascript">
function doAjaxPost() {
// get the form values
var name = $('#name').val();
var education = $('#education').val();
$.ajax({
type: "POST",
url: "AddUser",
data: "name=" + name + "&education=" + education,
success: function(response){
// we have the response
$('#info').html(response);
$('#name').val('');
$('#education').val('');
},
error: function(e){
alert('Error: ' + e);
}
});
}
</script>
</head>
<body>
<h1>Add Users using Ajax ........</h1>
<table>
<tr><td>Enter your name : </td><td> <input type="text" id="name"><br/></td></tr>
<tr><td>Education : </td><td> <input type="text" id="education"><br/></td></tr>
<tr><td colspan="2"><input type="button" value="Add Users" onclick="doAjaxPost()"><br/></td></tr>
<tr><td colspan="2"><div id="info" style="color: green;"></div></td></tr>
</table>
Show All Users
</body>
</html>
and my MvcConfiguration class since i'm using a java based configuration and not using XML
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = { "controllers" })
public class MvcConfig extends WebMvcConfigurerAdapter
{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// JSP VIEW-RESOLVER
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setOrder(2);
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
return bean;
}
}
EDIT: i starter a new project just for the sake of trying to know what error i'm having, i delete spring secuirty in my application, but i still can figure out whats wrong.
1) i actually dont delete spring security i just starte a new project to try to solve my url problem
2) i change my controllers and the URL attribute in my ajax script
new RequestMapping controllers:
#RequestMapping(value="AddUser",method=RequestMethod.GET)
i deleted the "/" in the value="AddUser"
i dont have a "/" in any of my controllers if put a "/" in the controllers i have the same 500 Internal server error

This might be because of the CSRF protection which is enabled by default in Java configuration. Try in your configuration...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.csrf().disable();
}
Let me know if this works.
EDIT**
To include CSRF token in AJAX request, if you are using JSON, you need to put it on the http header. Sample JSP example typically would be...
<html>
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>
Then in your javascript call, get this parameters and add it to XMLHttpRequest's header.
Hope this helps.
Further reading

In my case, i had to add the below dependency to my pom
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.2</version> </dependency>

Related

Display data on HTML using Thymeleaf

I would like to display the data I get from a search, personalized for my taste. At this moment, It is just plain text.
For example, I am searching for "Titanic", and I get the name, a few links, and some information from IMDB.
I have the following code:
search.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="#{/search}" th:object="${search}" method="post">
<p>Message: <input type="text" th:field="*{content}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
result.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'content: ' + ${main.content}"></p>
Submit another message
</body>
</html>
SearchController.java
#Controller
public class SearchController {
#GetMapping("/search")
public String greetingForm(Model model) {
model.addAttribute("search", new Main());
model.addAttribute("main", new Main().getContent());
return "search";
}
#PostMapping("/search")
public String greetingSubmit(#ModelAttribute Main main) {
return "result";
}
}
and Main.java
private String content;
private List<Result> finalList;
private List<Result> resultList;
public void setContent(String content) throws IOException {
//code to compute finalList
}
public List<Result> getContent() {
return this.finalList;
}
The main problem is that I have no ideea where to being with. finalList is a list of objects of type "Result", which have fields such as
private List<String> link = new ArrayList<>();
private String name;
private TitleProp titleProp;
and TitleProp has
private String trailer;
private String rating;
private String description;
private String genre;
I would like to manipulate each field to show it on a different way, such as a table with more rows, etc.
Any link or sample of code would help me a lot to understand Thymeleaf and Spring Boot more.
I am coming with an answer to my question. I managed to get the result I wanted using Ajax, as SnakeDoc suggested. It was a long road, mostly because even if I had a working code, I spent a few hours searching for the Forbidden 403 error on ajax post request.
So, for the js part:
function ajaxPost() {
// Here we prepare data for the JSON
var formData = {
moviename: $("#moviename").val()
}
$.ajax({
type: "POST",
contentType: "application/json",
url: "MYURL",
data: JSON.stringify(formData),
dataType: 'json',
success: function (result) {
{
$.each(result,
function (i, title) {
// do whatever you want with what you got from the server
});
console.log("Success: ", result);
}
console.log(result);
},
error: function (e) {
console.log("ERROR: ", e);
}
});
}
If this seems confusing, I access the fields you can see in my question by
title.name, title.link, title.titleProp.description, etc, inside function (i, title)'s body.
For the HTML,
<label for="moviename" style="margin-right:5px">Title:</label>
<input type="text" class="form-control" id="moviename" placeholder="Enter a title"/>
Where moviename is the variable name you get from the input.
Now, on the backend, we have to configure our path
#PostMapping("/MYURL")
public ResponseEntity<Object> addSearch(#RequestBody SearchCriteria searchCriteria)
throws IOException {
// do whatever you want to get a result. I used a custom class "SearchCriteria"
// which has a getter and a setter for the field
// **private String moviename;**
return ResponseEntity.ok(THIS GETS SENT TO AJAX);
}
The main problem was that I have web.security, and you have two choices. First one, you disabling csrf. You have to add this line to your security config.
http.csrf().disable();
in protected void configure(HttpSecurity http) method.
Or, you add csrf to the ajax request. More info on this topic was discussed here
With thymeleaf, you can display a list in html like so:
<tr th:each="student: ${students}">
<td th:text="${student.id}" />
<td th:text="${student.name}" />
</tr>
More info: https://www.baeldung.com/thymeleaf-iteration

Whitelabel Error Page : Spring Boot Application with Eclipse

I am trying to build an application with spring boot and java in eclipse.
What I have tried so far:
HomeController.class
#Controller
#ComponentScan(basePackages = {"project.tool.frontend"})
public class HomeController {
#GetMapping("/home")
public String home(){
System.out.println("open page");
return "home";
}
}
home.html
<!DOCTYPE HTML>
<html>
<head>
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="/home" method="get">
First name: <input type="text" name="fname"><br> Last
name: <input type="text" name="lname"><br> <input
type="submit" value="Submit">
</form>
</body>
</html>
Application.class
#SpringBootApplication
public class Application{
public static void main(String agrs[])
{
SpringApplication.run(Application.class);
}
}
When I run this Application I get the "Whitelabel ErrorPage" Error. I also enabled the whitelabel errorpage in my application.properties .
And a question for unserstandig: When I use #GetMapping("/home") in my HomeController and the <form action="/home" in my html file it will be mapped through the "/home" get method right?
Thank you all.
As a static resource, your home.html should be at resources/public/home.html (or /static/). Is it there?
Your Application should tell in which package your controller is located, so it gets picked up
Does adding a ComponentScan help?
#SpringBootApplication
#ComponentScan(basePackages = { "com.acme.controllers" })
public class Application{
}
If you have not configured any view resolver, try returning "/views/home.html" instead of just "home". Change "/views/home.html" to whatever be the path of the file.
I suggest using Thymeleaf as your viewresolver.
You can place the home.html in src/main/resources folder to be recognized.
As you are using .html extension then I suggest you to use the thymeleaf as a view resolver.
Using thymeleaf HTML:
<form th:action="#{/home}" th:method="get"
...
...
//Rest of your code goes here.
</form>
Use #ComponentScan annotation:
#SpringBootApplication
#ComponentScan(basePackages = { "<full package name where controller exists>" })
public class Application{
public static void main(String agrs[]){
SpringApplication.run(Application.class);
}
}

Why am I getting Bad Request kind error when uploading file using jquery with spring mvc?

When I am using Jquery with spring MVC I got an error at browser side "Bad Request" and control not going to the controller.While I am using simple form and sending a request to same controller then it is going.
Below is my code please tell me where am I going wrong?
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="files/jquery-1.10.2.js"></script>
<script src="files/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
var isJpg = function(name) {
return name.match(/jpg$/i)
};
var isPng = function(name) {
return name.match(/png$/i)
};
$(document).ready(function() {
var file = $('[name="file"]');
var imgContainer = $('#imgContainer');
$('#btnUpload').on('click', function() {
var filename = $.trim(file.val());
if (!(isJpg(filename) || isPng(filename))) {
alert('Please browse a JPG/PNG file to upload ...');
return;
}
$.ajax({
url: 'FileData.htm',
type: "POST",
data: new FormData(document.getElementById("fileForm")),
enctype: 'multipart/form-data',
processData: false,
contentType: false
}).done(function(data) {
imgContainer.html('');
var img = '<img src="data:' + data.contenttype + ';base64,'
+ data.base64 + '"/>';
imgContainer.append(img);
}).fail(function(jqXHR, textStatus) {
//alert(jqXHR.responseText);
alert('File upload failed ...');
});
});
$('#btnClear').on('click', function() {
imgContainer.html('');
file.val('');
});
});
</script>
</head>
<body>
<!-- <form name="dlgContent" action="FileData.htm" id="dlgcon" enctype="multipart/form-data" method="POST">
<input type="file" name="excelfile"/>
<input type="submit"/>
</form> -->
<div>
<form id="fileForm">
<input type="file" name="file" />
<button id="btnUpload" type="button">Upload file</button>
<button id="btnClear" type="button">Clear</button>
</form>
<div id="imgContainer"></div>
</div>
</body>
</html>
And my Controller Class in spring mapping given below
#RequestMapping(value="/FileData.htm", method = RequestMethod.POST)
public void FileData(Model model, #RequestParam CommonsMultipartFile[] excelfile, HttpServletRequest request, HttpServletResponse response){
System.out.println("bhjsbfjhsbfbdesfbsfb");
response.setContentType("application/json");
FileData fd = new FileData();
//Map<String, String> data = fd.submitFileData(excelfile);
Gson gson = new Gson();
// String values = gson.toJson(data);
try {
//response.getWriter().write(values);
//System.out.println(values);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
Thanks.
Actually you are sending Json and not html you should use #ResponseBody
#RequestMapping(value="/upload", method = RequestMethod.POST)
public #ResponseBody
FileData upload(MultipartHttpServletRequest request,
#RequestParam String albumName,
HttpServletResponse response) {
Iterator<String> itr = request.getFileNames();
//others code here
Also Don't forget !! to config multipart data ,
Plus send back Object using jackson lib to jquery done function to be work
Gson lib is not good to use with #ResponseBody , we are using Gson with RestTemplate instead.

Spring MVC-Response is not getting from controller using angular

I am implementing simple CRUD Operation using spring restful webservices and angular js.I trying to load all the details when the page is loading.But its not getting any response.
Controller :-
#RestController
public class EmployeeController {
public List<Employee> appList=new ArrayList<Employee>();
#RequestMapping(value="/employee",method=RequestMethod.GET)
public ModelAndView loadEmployee(){
return new ModelAndView("employee", "webemployee", new Employee());
}
#RequestMapping(value="/employees",method = RequestMethod.GET,headers="Accept=application/json")
public List<Employee>loadAllApps() {
Employee app=new Employee();
System.out.println(".........................loadAllApps.............");
app.setAppID("test_id");
app.setAppName("test_name");
appList.add(app);
return appList;
}
#RequestMapping(value="/employees/insert/{appID}/{appDescr}",method = RequestMethod.POST,headers="Accept=application/json")
public List<Employee> addApps(#PathVariable String appID,#PathVariable String appDescr) throws ParseException {
System.out.println("appID"+appID+"appDescr..........."+appDescr);
Employee app=new Employee();
app.setAppID(appID);
app.setAppName(appDescr);
appList.add(app);
return appList;
}
}
Jsp :-
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html ng-app="AppManger">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>WebService Example</title>
<script data-require="angular.js#*" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script>
</head>
<div ng-controller="appController">
<div>
<table>
<tr ng-repeat="app in appList">
<td >{{ app.appID }}</td>
<td >{{ app.appName }}</td>
</tr>
</table>
</div>
<script type="text/javascript">
var appModule = angular.module('AppManger', []);
appModule.controller('appController', function ($scope,$http) {
var url="http://localhost:8080/Apps";
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$http.get(url+'/employee').
success(function(data, status, headers, config) {
alert(status);
$scope.appList = data;
});
});
</script>
</script>
</html>
when i am trying to checking status value in $http.get method.its not showing any alert message.Please let me know what issues here.
You seem to call your /employee endpoint but expecting a list of employees , because you assigning data response to the:
$scope.appList = data;
First, change that to the other endpoint you created (/employees) which returns the list.
What is the servlet-path of your mvc dispatcher servlet? This would be my first point of failure to check for. I see that you call:
var url="http://localhost:8080/Apps";
Does that mean that you deploy your app in context 'Apps' or is that your servlet path? If this is the context name then I assume that mvc is resolved to the 'root' path i.e. '/'. If not, check what is servlet path for the dispatcher and add that to your url (on the client side). This would explain why you get 404.
And also, check that you can call your API directly in the browser to rule out the server-side errors as user Chandermani suggested.

How to manage error message in Spring MVC

I am new to spring MVC .My abc page is have one submit button. On click of submit button, abcHandler called which is inside xyzController.
Just wondering how to achieve this scenario.
-- If some error occurs then it should return some message.
-- It should stay in the same page , for me its abc page.
I have tried this.The problem I am facing is that , i am getting the alert message as "You must have something...",
but it is navigating to error page means a blank page. This is not suppose to happen.I want to show the message and stay in the same page.
How can i achieve easily with spring MVC.
Please suggest some idea.
public class xyzController extends MultiActionController implements InitializingBean {
public ModelAndView abcHandler(HttpServletRequest request,HttpServletResponse response)throws Exception {
// session
HttpSession session = request.getSession(true);
String abc = "";
if(abc != ""){
}else{
String error = "You must have xyzzzzzz";
return new ModelAndView("2.0/error", "downloaderror", error);
}
return new ModelAndView();
}
}
My error.jsp is like this
<!DOCTYPE html>
<html>
<head>
<script src="abc/js/jquery-1.9.0.min.js"></script>
</head>
<body>
<c:if test="${not empty downloaderror}">
<script>
alert("You must have something...");
</script>
</c:if>
</body>
</html>
You can implement HandlerExceptionResolver on your own.Refer to this tutorial: http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
Add an error flag in controller method like this
public ModelAndView abcHandler(HttpServletRequest request, HttpServletResponse response)throws Exception {
ModelAndView model=new ModelAndView();
model.addObject("error", true);
return model;
}
In JSP
<!DOCTYPE html>
<html>
<head>
<script src="abc/js/jquery-1.9.0.min.js"></script>
</head>
<body>
<c:if test="${error}">
<script>
alert("You must have something...");
</script>
</c:if>
</body>
</html>
You can achieve the scenario by going in following way:
import org.springframework.web.servlet.ModelAndView;
public ModelAndView abcHandler(HttpServletRequest request, HttpServletResponse response)throws Exception {
ModelAndView model=new ModelAndView();
model.addObject("ERROR_CODE", "Error Occurred");
model.setViewName("page1");
return model;
}
and your jsp page will be like following:
page1.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<body>
<c:if test="${!empty ERROR_CODE }">
<c:out value="${ERROR_CODE }"></c:out>
</c:if>
</body>
</html>
On validation failure do not return to error page, instead return to same page so your code in else block should be
}else{ String error = "You must have xyzzzzzz";
return new ModelAndView("2.0/error", "downloaderror", abc); }
And also store the errormessage in your modelmap against some key like "errormsg" and on your abc page check for this key and then print the message.

Categories

Resources