Json as parameter to Grails controller - java

I am trying to pass a Json array to a Grails controller and then to a Java class. I can't figure out how to properly pass my params to the Java class though. Here is the relavent code.
AJAX POST:
$('#matrixForm').submit(function(e) {
e.preventDefault();
var matrixArray = $(this).serializeArray();
$.ajax({
type: "POST",
data: matrixArray,
url: "/turingpages/factorize/create",
success: function(data) {
//USE DATA
}
});
});
Grails Controller:
...
def create() {
MatrixFactorization m = new MatrixFactorization(params)
Gson gson = new Gson()
def jsonMatrix = gson.toJson(m.answer)
render jsonMatrix
}
...
MatrixFactorization Constructor:
public MatrixFactorization(JsonElement jsonarray) {
BlockRealMatrix R = GsonMatrix.toMatrix(jsonarray);
this.run(R);
}
My console shows my Json array as:
[{name:"00", value:"1"}, {name:"01", value:"2"}, {name:"02", value:"3"}, {name:"10", value:"4"}, {name:"11", value:"0"}, {name:"12", value:"4"}, {name:"20", value:"0"}, {name:"21", value:"4"}, {name:"22", value:"2"}]
My stack trace is:
| Error 2013-01-18 00:30:23,792 [http-bio-8080-exec-4] ERROR errors.GrailsExceptionResolver - GroovyRuntimeException occurred when processing request: [POST] /turingpages/factorize/create - parameters:
21: 4
20: 0
10: 4
22: 2
00: 1
01: 2
11: 0
02: 3
12: 4
failed to invoke constructor: public matrices.MatrixFactorization(com.google.gson.JsonElement) with arguments: [] reason: java.lang.IllegalArgumentException: wrong number of arguments. Stacktrace follows:
Message: failed to invoke constructor: public matrices.MatrixFactorization(com.google.gson.JsonElement) with arguments: [] reason: java.lang.IllegalArgumentException: wrong number of arguments
Line | Method
->> 15 | create in turingpages.rest.MFController$$ENuqtska
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread
I am very new to using JSON. Any help is appreciated. Thanks.

1.
jQuery will pass this data as request parameters, not JSON, by default. So you should build a JSON string to pass to jQuery. I can recommend you JSON 3 library. At this case it going to be:
$.ajax({
type: "POST",
data: JSON.stringify(matrixArray),
url: "/turingpages/factorize/create",
success: function(data) {
//USE DATA
}
});
2.
On server side you could also use standard Grails JSON converter (but you could use Gson, if you prefer), see http://grails.org/Converters+Reference.
At this case you can use
def create() {
MatrixFactorization m = new MatrixFactorization(request.JSON)
render m.answer as JSON
}

Related

My grails project facing error"TransactionRequiredException:no transaction" using domain.save(flush:true).save() it can is saving but updating

package com.fhjony.ocbt
import grails.web.servlet.mvc.GrailsParameterMap
class MemberService {
def save(GrailsParameterMap params) {
Member member = new Member(params)
def response = AppUtil.saveResponse(false, member)
if (member.validate()) {
member.save(true)
if (!member.hasErrors()){
response.isSuccess = true
}
}
return response
}
def update(Member member, GrailsParameterMap params) {
member.properties = params
def response = AppUtil.saveResponse(false, member)
if (member.validate()) {
member.save(flush: true)
if (!member.hasErrors()){
response.isSuccess = true
}
}
return response
}
def getById(Serializable id) {
return Member.get(id)
}
def list(GrailsParameterMap params) {
params.max = params.max ?: GlobalConfig.itemPerPage()
List<Member> memberList = Member.createCriteria().list(params) {
if (params?.colName && params?.colValue) {
like(params.colName, "%" + params.colValue + "%")
}
if (!params.sort) {
order("id", "desc")
}
}
return [list: memberList, count: memberList.totalCount]
}
def delete(Member member) {
try {
member.delete(flush: true,failOnError:true)
} catch (Exception e) {
println(e.getMessage())
return false
}
return true
}
}
Error message:
URI /member/update Class
javax.persistence.TransactionRequiredException Message null Caused by
no transaction is in progress
Line | Method
->> 211 | invoke in org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 188 | invoke in org.grails.core.DefaultGrailsControllerClass | 90 | handle . . . .
. in org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter | 1039
| doDispatch in
org.springframework.web.servlet.DispatcherServlet | 942 | doService
. . . in '' | 1005 | processRequest in
org.springframework.web.servlet.FrameworkServlet | 908 | doPost . .
. . . in '' | 882 | service in '' | 77 |
doFilterInternal in
You want your database interactions to be happening in a transactional context. One simple piece of that is you can mark your service class with #grails.gorm.transactions.Transactional.
Separate from that, and this isn't really related to your question, but passing GrailsParameterMap map around as a method argument is an unusual thing to do. What the right thing to do is depends on some factors in your app and you may want to pass values into your service rather than the whole map but if you really want the whole map in the service, one way to get there is by way of WebAttributes.
import grails.gorm.transactions.Transactional
import grails.web.api.WebAttributes
#Transactional
class MemberService implements WebAttributes {
def serviceMethod() {
// you can access params here because
// WebAttributes provides access to it
Member member = new Member(params)
// ...
}
}

Message: mysqli::query(): Couldn't fetch mysqli

I have a connection error...
Im using an API Restful for connect my Android App with DataBase(MySql)
api.php:
require_once 'vendor/autoload.php';
require 'funciones.php';
$app = new \Slim\Slim();
$db = new mysqli("XX.XXX.XXX.XXX", "user_BD", "pass_BD", "name_BD");
.
.
.
$app->get("/sp_login_principal/:user/:pass", function($user,$pass) use($db, $app) {
// sleep(3);
$query = $db->query("SELECT * FROM usuarios WHERE
user = '".$user."'
***line 63:*** AND password= '".$pass."' ;");
$usuarios = array();
while ($fila = $query->fetch_assoc()) {
$usuarios[] = $fila;
}
utf8_encode_deep($usuarios);
echo json_encode($usuarios);
});
"line 63:" it's only a commet, is not really in the code.
When i use the next url to call the select:
http://XXXX.000webhostapp.com/eldo/slim/api.php/sp_login_principal/useraname/passxxxx
I have the next error:
*
Slim Application Error
The application could not run because of the following error:
Details
Type: ErrorException
Code: 2
Message: mysqli::query(): Couldn't fetch mysqli
File: /storage/XXX/XXX/XXXXXXX/public_html/eldo/slim/api.php
Line: 63
Trace
#0 [internal function]: Slim\Slim::handleErrors(2, 'mysqli::query()...', '/storage/XXXX/2...', 63, Array)
#1 /storage/XXXX/XXX/XXXXXXX/public_html/eldo/slim/api.php(63): mysqli->query('SELECT * FROM u...')
#2 [internal function]: {closure}('username', 'passxxxx')
#3 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/vendor/slim/slim/Slim/Route.php(468): call_user_func_array(Object(Closure), Array)
#4 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/vendor/slim/slim/Slim/Slim.php(1357): Slim\Route->dispatch()
#5 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/vendor/slim/slim/Slim/Middleware/Flash.php(85): Slim\Slim->call()
#6 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/vendor/slim/slim/Slim/Middleware/MethodOverride.php(92): Slim\Middleware\Flash->call()
#7 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/vendor/slim/slim/Slim/Middleware/PrettyExceptions.php(67): Slim\Middleware\MethodOverride->call()
#8 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/vendor/slim/slim/Slim/Slim.php(1302): Slim\Middleware\PrettyExceptions->call()
#9 /storage/XXX/XXX/XXXXXX/public_html/eldo/slim/api.php(1164): Slim\Slim->run()
#10 {main}
*
I think the error is in the server file, because i used the same code on another server withoud problems.
Thanks!

How can I update User's details in grails with spring security before login With Remember Me Check?

I am using grails where authetication is done by Spring Security.I need to unlock User's account before login
#Transactional(readOnly=true, noRollbackFor=[IllegalArgumentException, UsernameNotFoundException])
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = User.findByUsername(username)
// Check and unlock account if 24 Hrs has been passed
userService.checkAndUnlockAccountAfter24Hrs(user.id);
if (!user) throw new NoStackUsernameNotFoundException()
def roles = user.authorities
// or if you are using role groups:
// def roles = user.authorities.collect { it.authorities }.flatten().unique()
def authorities = roles.collect {
new SimpleGrantedAuthority(it.authority)
}
return new MyUserDetails(user.username, user.password, user.enabled,
!user.accountExpired, !user.passwordExpired,
!user.accountLocked, authorities ?: NO_ROLES, user.id,
user.name)
}
Now when I do login with Remember Me check, Then It shows error:
-
| Error 2017-04-18 12:24:40,426 [http-bio-8080-exec-3] ERROR
[/].[default] - Servlet.service() for servlet [default] in context
with path [] threw exception
Message: retrieveUser returned null - a violation of the interface contract
Line | Method
->> 76 | attemptAuthentication in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 49 | doFilter in ''
| 82 | doFilter . . . . . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 100 | doFilter in com.brandseye.cors.CorsFilter
| 1145 | runWorker . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run . . . . . . . . . in java.lang.Thread
You have three options:
Comment out that code in boostrap in every run; except first time.
Drop database and create database for every single run
Hacky way:
Use condition(ternary operator) like this:
def adminRole = Role.findByAuthority('ROLE_ADMIN') ? : new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = Role.findByAuthority('ROLE_USER') ? : new Role(authority: 'ROLE_USER').save(flush: true)
def adminUser = User.findByUsername('admin') ? : new User(username: 'admin', password: 'admin', enabled: true).save(flush: true)
def user = User.findByUsername('user') ? : new User(username: 'user', password: 'user', enabled: true).save(flush: true)
if (!adminUser.authorities.contains('ROLE_ADMIN')) {
UserRole.create(adminUser, adminRole)
}
if (!user.authorities.contains('ROLE_USER')) {
UserRole.create(user, userRole)
}

Java ASSERTION error in grails

I am getting the following error:
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 844
| Error 2014-08-28 09:25:11,399 [http-bio-8080-exec-5] ERROR errors.GrailsExceptionResolver - StackOverflowError occurred when processing request: [GET] /api/getProduct - parameters:
id: 14
Stacktrace follows:
Message: Executing action [getProduct] of controller [project.ApiController] caused exception: Runtime error executing action
Line | Method
->> 198 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
my domains are as follows:
class Product {
String name
String comments
static hasMany = [components:Components]
public asJSON(){
println "product: "+this.id
def builder = new groovy.json.JsonBuilder()
def root = builder {
id this.id
name this.name
comments this.comments
components this.components.collect {it.asJSON()}
}
return builder.toString().replaceAll(/\\"/, '"').replaceAll(/\"\{/,'{').replaceAll(/\}\"/,'}')
}
}
Component:
class Components {
Product part_of
static hasMany = [alternatives:Alternatives]
public String asJSON(){
def builder = new groovy.json.JsonBuilder()
def root = builder {
id this.id
product (this.part_of)?this.part_of.asJSON():null
// alternatives (this.alternatives)?this.alternatives.collect {it.product.productAsJSON()} :null
}
return builder.toString()
}
}
When I do the following I get the exception
Product.get(1).asJSON()
I have checked that it is not recursively calling itself.
Product 1 have one Component which has a Product instance called part_of which is product with the ID 5

Groovys XmlParser ignores CDATA CR/CL

I want to parse a log4j generated xml log. Within the xml is a node with a throwable (if any). This (multiline, tabbed) text is encapsulated in a CDATA tag.
This is an excerpt of the whole file:
<log4j:event logger="org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver" timestamp="1330083921521" level="ERROR" thread="http-8080-1">
<log4j:message><![CDATA[Exception occurred when processing request: [GET] /test/log/show
Stacktrace follows:]]></log4j:message>
<log4j:throwable><![CDATA[org.xml.sax.SAXParseException: XML document structures must start and end within the same entity.
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at test.LogController$_closure2.doCall(LogController.groovy:21)
at test.LogController$_closure2.doCall(LogController.groovy)
at java.lang.Thread.run(Thread.java:662)
]]></log4j:throwable>
</log4j:event>
I parse it with groovys XmlParser:
def parser = new XmlParser(false, false).parse(new File("stack.log"))
return parser.'log4j:event'.collect { l ->
LogEntry entry = new LogEntry()
entry.with {
level = l.'#level'
message = l.'log4j:message'.text()
thread = l.'#thread'
logger = l.'#logger'
timestamp = new Date(l.'#timestamp' as long)
throwable = l.'log4j:throwable'?.text() ?: ''
}
entry
}
The 'throwable' field contains all the text but without CR/LF.
Does anybody know how to cope with that?
Thanks in advcance...
Hate to just throw code at you, but it seems to work as expected and returns the CRLFs
def xml = '''<log>
| <log4j:event logger="org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver" timestamp="1330083921521" level="ERROR" thread="http-8080-1">
| <log4j:message><![CDATA[Exception occurred when processing request: [GET] /test/log/show
|Stacktrace follows:]]></log4j:message>
| <log4j:throwable><![CDATA[org.xml.sax.SAXParseException: XML document structures must start and end within the same entity.
| at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)
| at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
| at test.LogController$_closure2.doCall(LogController.groovy:21)
| at test.LogController$_closure2.doCall(LogController.groovy)
| at java.lang.Thread.run(Thread.java:662)
|]]></log4j:throwable>
| </log4j:event>
|</log>'''.stripMargin()
class LogEntry {
def level
def message
def thread
def logger
def timestamp
def throwable
String toString() {
"""EVENT:
| level : $level
| message : $message
| thread : $thread
| logger : $logger
| ts : $timestamp
| thrown : $throwable""".stripMargin()
}
}
def parser = new XmlParser(false, false).parseText( xml )
def entries = parser.'log4j:event'.collect { event ->
new LogEntry().with {
level = event.#level
message = event.'log4j:message'.text()
thread = event.#thread
logger = event.#logger
timestamp = new Date( event.#timestamp as long )
throwable = event.'log4j:throwable'?.text() ?: ''
it
}
}
entries.each {
println it
}
That prints:
EVENT:
level : ERROR
message : Exception occurred when processing request: [GET] /test/log/show
Stacktrace follows:
thread : http-8080-1
logger : org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver
ts : Fri Feb 24 11:45:21 GMT 2012
thrown : org.xml.sax.SAXParseException: XML document structures must start and end within the same entity.
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at test.LogController$_closure2.doCall(LogController.groovy:21)
at test.LogController$_closure2.doCall(LogController.groovy)
at java.lang.Thread.run(Thread.java:662)
Which has CRLF chars in it where they are supposed to be...
This is with Groovy 1.8.6 btw... What version are you using? Can you upgrade and try again?
The xml standard calls for white space to be normalized during the parse.
I'm not sure, but the parser may have a setting to override this behavior. Otherwise, you could pre-process the file, replacing line endings inside c data sections with their xml entity equivalents, and then parse it.

Categories

Resources