JSON unexpected token at Object.parse - java

I am working with Spring Security and trying to display role of the user that is loged in.
Spring Sec is functioning - I have working register and login JS functions(I can see new user in database, and I can do a valid login) but when I try to get role info for the current user and display it via simple {{role}} in simple html file in frontend i get this error:
But I still get a valid response from JSON:
This is my user.html where data-ng-init and {{role}} are:
<div class="masthead">
<h4 class="text-center" data-ng-init="init()">
<strong>Users Home Screen</strong>
</h4>
<p>{{role}}</p>
<br>
...
</div>
This is my userController.js (it's connected to user.html via app.js):
collectionsApp.controller('userController', function($scope, userService,
$state) {
$scope.init = function() {
userService.getAuthorization(displayRole);
}
displayRole = function(response) {
$scope.role = response.data;
}
});
My userService.js:
collectionsApp.service('userService', function($http) {
return {
login : function(user, callback) {
$http.post('/user/login', user).then(callback);
},
register : function(user, callback) {
$http.post('/user/add', user).then(callback);
},
getAuthorization : function(callback) {
$http.get('/user/getAuthorization').then(callback);
}
};
});
My UserController.java (only function of interest is displayed in this post):
#RequestMapping(value = "/getAuthorization", method = RequestMethod.GET)
public String getAuthorization() {
return SecurityContextHolder.getContext().getAuthentication().getAuthorities().toString();
}
Oh, and one more strange thing:
When I put break-point, like shown on image below, and hit f5 on user.html, debugging acts like it never reaches the break point and reports mentioned SyntaxError in console. That is rather paranormal if you ask me... :)

Your response is not valid JSON. ["SOME_ROLE"] would be generated if you convert to JSON an array containing the single String element "SOME_ROLE". If you are using Google's Gson library, you can do:
Gson gson = new Gson();
gson.toJson(new String[]{SecurityContextHolder.getContext().getAuthentication().getAuthorities().toString‌​()});

Related

How display Java Object by ajax calls

I have Spring 4 MVC web app, I would like to do a GET call with Ajax that returns a list of simple object. Suppose that the object is something like this:
class Categories {
String name;
}
and calls is like this:
function getCategories() {
$.ajax({
type: "GET",
url: "categoryFilter.html",
dataType: "json",
success: function (result) {
alert(result);
},
error: function (result) {
alert("error");
}
});
}
Than I would like to display this object inside a Spring form like this:
<form:form method="post" action="searchShop.html" modelAttribute="Categories">
<c:forEach var="cat" items="${result}">
<span><form:input path="nome" value="${cat.name}" /></span>
</c:forEach>
</form:form>
I googling around and I see that I can append the result into a div or something similar but I can do something like that?
Thanks for your reply. My controller is:
#RequestMapping("/categoryFilter")
public Response showCategory() {
List<Categoria> categoryList = categoryService.getAllCategories();
Response response = new Response("Done", categoryList);
return response;
}
and the Object response:
public class Response {
private String status;
private Object data;
....
}
I have tried many different ways, with #GetMapping and so on.. but I always received 404 bad request.
Thanks a lot
Yes yes my question was how convert the pojo automatically with jackson library but after Spring 3 I needs a lot of bean configuration and than I modify my controller as follows:
#ResponseBody
#RequestMapping("/categoryFilter")
public String showCategory() {
List<Categoria> catList = categoryService.getAllCategories();
JSONArray json = new JSONArray(catList);
return json.toString();
}
Your code:
var resObjs= JSON.stringify(result);
var cats= JSON.parse(resObjs);
$("#category-form").append('<form:form method="post" action="searchShop.html" modelAttribute="Categoria">');
$.each(JSON.parse(cats), function(i, obj) {
$("#category-form").append('<form:input path="nome" value="'+obj.nome+'" />' + obj.nome); // this line
});
$("#category-form").append('<input type="submit" value="Submit"/>');
$("#category-form").append('</form:form>');
Please take a look to the line inside the $.each, that line visualiza an input type with value the string +obj.name+ follows by the effective value of variable (the name of category).. why I can't put dinamically value right there?? I'm going mad..
Thank you
yes you can append the json values to a div, this is what i did for populating selection dropdown with json data, something similar can be done for forms as well.
success: function (responseJson) {
var responseObjects= JSON.stringify(responseJson);
var categories= JSON.parse(responseObjects);
$('#divid').empty();
$('#divid').append($('<option value="0">').text("Select Variant"));
$.each(categories, function(i, obj) { $("#divid").append(('<option>
</option>').val(obj.id).html(obj.value));});
}

How to fire or execute http service when link is clicked in angular route in single page web app?

Requirement : I want to click on a menu item which is in single page app and by clicking on that link, loads a view employee.html via $routeProvider and the view should load my employee details by the help of angular service.
In short - executing an angular service on view load by angular route
I do not know the angular code from beginning to end
Following is the Code:
/Spring MVC controller which returns a list in JSON format/
#ResponseBody
#RequestMapping(value="/details", method=RequestMethod.GET)
public List<Employee> details() throws Exception {
List<Employee> employeeList = employeeService.getEmployees();
return employeeList;
}
/* JSON which is returned is : */
[{"employeeId":111,"fName":"John"},
{"employeeId":112,"fName":"Peter"},
{"employeeId":113,"fName":"Brad"}]
<!--HTML-->
<body ng-app="myApp">
<div ng-controller="employeeCtrl">
<!-- http://localhost:8080/web/details/ is the Spring Java URL from which I get the JSON -->
Get All Employees
Link2
<div ng-view></div>
</div>
</div>
/* AngularJS */
var app = angular.module(["myApp"]);
app.config(function ($routeProvider) {
$routeProvider
.when("??", { /* dont know the URL to be entered here */
templateUrl: "views/employees.html"
})
});
});
You got it backwards. The link in your template should not point to the backend URL from which you get the JSON. It should point to the URL of the route displaying the employees. For example:
Get All Employees
and
$routeProvider.when("/employees", {
templateUrl: "views/employees.html",
controller: "EmployeesController"
})
Then, in the EmployeesController, use the $http service to get the employees as JSON from the backend:
$http.get('/web/details').then(function(response) {
$scope.employees = response.data;
});
I would change the mapping from /details to /employees, too, since that's what you get from that URL.

Dropwizard / Jackson returns HTTP code 200 from function but AJAX POST gets error

I am new to Dropwizard and am having a little trouble with the conversion from POJO to Json. I am using jQuery at the frontend where I am calling the ajax function with the type POST. I am trying to validate a login against data in a MySQL database. I know the database is connected and the correct user can be located in the database based on the credentials entered on the HTML login page.
Here is the backend code:
#POST
#UnitOfWork
#Path("/login")
#Produces("application/json")
public User login(String credentials) {
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readValue(credentials, JsonNode.class);
String username = root.get("Username").toString().replaceAll("\"", "");
String password = root.get("Password").toString().replaceAll("\"", "");
User user = userDAO.findByUsername(username);
//Check password matches and respond
boolean passwordMatched = user.isPasswordMatched(password);
//Return correct response
if (passwordMatched) {
return user;
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
Then at the front end I simply post the username and password to the url:
$(document).ready(function() {
$("#login").click(function() {
var username = $("#username").val();
var password = $("#password").val();
$.ajax({
url:'http://localhost:8080/User/login',
type: 'POST',
data: JSON.stringify({"Username" : username, "Password" : password}),
complete: function(data, status) {
alert("Status: " + status + "Data: " + JSON.stringify(data));
}
});
The console output from the server is HTTP code 200 and when I set a breakpoint in the login function I can see the correct database entry being found and being returned from function. However, the alert that is triggered on complete from the jQuery code prints an error.
The data returned from my server is valid JSon according to JsonLint. So it looks like ajax is not receiving the data which is strange because it sends the original login details successfully. Can anyone help with this?
Following the answer at Enabling cors in dropwizard not working seemed to fix my issue. It was a problem with CORS.

Spring Security CSRF Token not working with AJAX

I have a problem in my spring boot app with the csrf token.
I have a form where I can edit a Person. A Person can have
Let us now imagine that the person has a car and enter this and store it. The next time he wants to delete this car and enter another one. I have created that so that there is a list of all of his cars -- he has the option to remove this from the list. Now I'm starting from these pills and want to send with the corresponding ID to the server a POST. When I try I get a 403 forbidden and I have no idea why.
If I change from POST to GET, then it works.
My JavaScript (taken from this site: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag)
var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
var csrfHeader = $("meta[name='_csrf_header']").attr("content");
var csrfToken = $("meta[name='_csrf']").attr("content");
// using JQuery to send a non-x-www-form-urlencoded request
var headers = {};
headers[csrfHeader] = csrfToken;
$.ajax({
url: "./delete/car",
type: "GET",
headers: headers,
});
$.ajax({
url: "./delete/car",
type: "POST",
headers: headers,
});
My controller methods:
#RequestMapping(value = "/{login}/delete/car", method = RequestMethod.GET)
public ModelAndView delete(#PathVariable("login") final String login) {
System.out.println("Stop");
return new ModelAndView("redirect:" + WebSecurityConfig.URL_PERSONS_OVERVIEW);
}
#RequestMapping(value = "/{login}/delete/car", method = RequestMethod.POST)
public ModelAndView deleteInstEmp(#PathVariable("login") final String login) {
System.out.println("Stop");
return new ModelAndView("redirect:" + WebSecurityConfig.URL_PERSONS_OVERVIEW);
}
Any suggestions?
Thanks in advance.
OK, after strugglin with all that, I get the following result.
I added the fail method to the Ajax construct and get the following message:
"Failed to execute 'setRequestHeader' on 'XMLHttpRequest': '${_csrf.headerName}' is not a valid HTTP header field name."
the official spring site advises that you have to put this: <sec:csrfMetaTags /> or from other sources, this: <meta name="_csrf" th:content="${_csrf.token}"/> in your html file.
After this, you should be able to access these attributes in your JavaScript, but in my case I get undefined and ${_csrf.headerName}.
A last try was to take the value from the hidden value (chapter 24.5: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag).
Now, I have the following:
$(function () {
var token = $("input[name='_csrf']").val();
var header = "X-CSRF-TOKEN";
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
$.ajax({
url: "./delete/car",
type: "POST",
success:function(response) {
alert(response);
}
});
With this it works like a charm.
Another way, you can use the following code:
$.ajax({
url : './delete/car',
headers: {"X-CSRF-TOKEN": $("input[name='_csrf']").val()},
type : 'POST',
success : function(result) {
alert(result.msgDetail);
}
})
I suggest you first check if a valid csrf token and the header have been generated using chrome debugger. If not, then have you added the <sec:csrfMetaTags /> in the <head>?(you will need to import the spring security taglibs). If using Apache tiles, you will have to add this at the <head> section of the template file being used for the view.
If the token is not empty, then in your security-context/configuration file, check if you have disabled csrf security by any chance. By default it is enabled and needs to be for this process to work.

Springs MVC JSON Response and convert it to JS Object

I am having a question that how can I send JSON Object from Springs MVC so that I can convert it into a JavaScript Object on my HTML Page.
In a traditional way I do it: Below is a snippet from Java Servlet which sets a request attribute and forward it to the JSP Page.
JSONObject jsonObj = new JSONObject();
jsonObj.put("name","test");
jsonObj.put("age",24);
request.setAttribute("jsonObj",jsonObj);
request.getRequestDispatcher("test.jsp").forward(request,response);
In JSP I retrieve as :
<script type="text/javascript">
var jsonObj =<%=request.getAttribute("jsonObj"); %>;
alert("name = "+jsonObj.name+" ; age = "+jsonObj.age); // This will output name and age from the JSON Object
</script>
So what I need to ask how can I do the same in Springs MVC. How can I send the JSONObject from Dispatcher Servlet, and convert it to JS object in my JSP page ?
An easy way to do this using the ObjectMapper. It will create an JSON String from your Object. And that you can send to your view/jsp.
I put an small example of a controller I do this (just snipped).
#Controller
public class UsersSettingsController {
#Autowired
UserSettingsDefaultService userSettingsService;
#RequestMapping(value="/userSettings/dynamic/userSettings", method=RequestMethod.GET)
public ModelAndView get() throws Exception {
ModelAndView mav = new ModelAndView();
ObjectMapper mapper = new ObjectMapper();
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserSettings userSet = userSettingsService.getUserSettingsByUser(user);
mav.addObject("userSettingsJSON", mapper.writeValueAsString(userSet));
mav.setViewName("userSettings/dynamic/filter");
return mav;
}
}
Or course can you create your JSON Object in your Contoller step by step like you did in your example. Then you don't need the Mapper, just sending the String to your View.
In the JSP you load the json String like this into a JS var:
var jsonString = '${userSettingsJSON}';
To get elements from JSON String or parse, see: http://www.json.org/js.html.
I'm an KnockOut Framework Fan would do it with it.
I think you should use ajax(for example jquery),the following is spring mvc
#RequestMapping(value = "/admin/new/list", method = RequestMethod.GET)
#ResponseBody
public List<News> list()
{
return newsDao.findAll();
}
and in the jsp page,you may use ajax util (for example jquery)
$.ajax({
type: "GET",
url: '<c:url value="/admin/new/list"/>',
cache:false,
dataType :'json',
success: function(data){
alert(data);
}
});
the data is json object
I don't know whether the above is what you need
A much easier way to do this is to include the Jackson dependencies in maven and use #ResponseBody to return a JSON representation of the object, without having to manually write the manipulation.
Have a look at the example below, you shouldn't have to write any tranlation to JSON code.
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/
As per your requirement, I suggest you to use AJAX call with JSON as data type.
For example :
$.ajax({
url: "getFormatIdDescMap?compId="+compId,
global: false,
type: "POST",
dataType:"json",
contanttype:'text/json',
async:false,
error:function(){
alert("Error during retrieving the foramt ID List");
},
success: function(data){
//REMOVE ALL THE OLD VALUES OF FORMAT DROP DOWN
removeDropDownVals('formatList');
var optn;
for(var index=0;index<data.formatKeys.length;index++){
optn = document.createElement("option");
document.getElementById("formatList").options.add(optn);
optn.text =data.formatDescs[index];
optn.value=data.formatKeys[index];
}
}
});
});
In the code above, I am preparing a new list of Formats based on company ID. You can iterate over the response.
It will give response text as per your requirements. But here note that .. if you are getting json Array in the response, it will contain that data in square bracket like..[1,2,3] and If you are getting response in JSON Object then it will be displayed in curly braces like {"data",[1,2,3]}.

Categories

Resources