Showing posts with label grails 5. Show all posts
Showing posts with label grails 5. Show all posts

Tuesday, August 16, 2022

Convert Date to Pretty Time in Grails and Groovy

In this tutorial, we will learn how to convert Java Date to pretty time like moments ago, 1 hour ago, 1 week ago, 1 month ago, 1 year ago, and so on in grails application.

For this, we are using the prettytime plugin in our project.

Load PrettyTime in Grails Gradle project:

Add the following inside dependencies in the build.gradle file.

dependencies {
//other dependencies
 
compile 'org.grails.plugins:grails-pretty-time:4.0.0'
}

PrettyTime format Date:

Now let's create a method that formats the Java Date

import org.ocpsoft.prettytime.PrettyTime
import java.util.Date
public static String formatPrettyTime(Date date) {
        PrettyTime p = new PrettyTime()
        return p.format(date).trim()
    }

This will format the given date to a pretty time like moments ago.

Pretty Time Support Locale:

Prettytime supports different languages, for this use request to get the current locale and format it.

public static String formatPrettyTime(Date date, request) {
        Locale locale = RequestContextUtils.getLocale(request)
        PrettyTime prettyTime = new PrettyTime(locale)
        return prettyTime.format(date).trim()
    }

Here, we are using the locale from the request which gives the session locale for the current user

Current locale in grails application can also be achieved using LocaleContextHolder

import org.springframework.context.i18n.LocaleContextHolder
Locale locale = LocaleContextHolder.getLocale()

For pretty time supported language please follow prettyTime

Use in Gsp page:

If we are using the GSP pages HTML as server-side rendering, then we can use pretty time in GSP pages as below

<prettytime:display date="${someDate}" />
Share:

Sunday, July 24, 2022

How to parse JSON string to Object and vice versa in Groovy Grails application

In this tutorial, we will learn how to parse or convert the object to JSON string and JSON string to object.

Convert Object to JSON String:

Let's look into the example, here we will parse the Map to JSON string.

Map mapToConvert = [username : "Test", phonenumber : "+10656564"]
List listToConvert = ["Test", "+10656564"]

Now, let's convert to JSON string using JSON class

import grails.converters.JSON
        Map mapToConvert = [username : "Test", phonenumber : "+10656564"]
        List listToConvert = ["Test", "+10656564"]
        String jsonStringFromMap =  (mapToConvert as JSON).toString()
        String jsonStringFromList =  (listToConvert as JSON).toString()
        

You can use any other object data type to convert as above

Convert JSON String to Object:

For converting JSON string to object we are using JsonSlurper as below:

import grails.converters.JSON
import groovy.json.JsonSlurper
		Map mapToConvert = [username : "Test", phonenumber : "+10656564"]
        List listToConvert = ["Test", "+10656564"]
        String jsonStringFromMap =  (mapToConvert as JSON).toString()
        String jsonStringFromList =  (listToConvert as JSON).toString()
        Map convertedMap = parseTo(jsonStringFromMap)
        List convertedList = parseTo(jsonStringFromList)
        
        private static def parseTo(String jsonString) {
        return new JsonSlurper().parseText(jsonString)
    }
        
Share:

Thursday, July 7, 2022

How to use custom validation class in Grails Application

In this tutorial, we will learn how to add custom validation in the Grails application.

Grails domain classes support the validation by default. So we can simply add the constrains for the domain classes fields as below

class User {
    String username
    String password
    String email
    Integer age
    
    
	static constraints = {
        username blank: false, unique: true
        password size: 5..15, blank: false
        email email: true, blank: false
        age min: 18
	}
}

Now we can simply validate the object using validate() or hasErrors() methods

User user = new User(params) // map the request parameters to user object
if (!user.validate()) {
    // format errors and send to the client
}
User user = new User(params) // map the request parameters to user object
if (user.hasErrors()) {
    // format errors and send to the client
}

Now, let's say that we want to validate some non-domain fields or use a custom validation class to validate the request parameter sent by the user.

We can do so by implementing Validateable trait so that we can add the constrain for the fields in the custom class. Let's look into the example

import grails.validation.Validateable

class UserCommand implements Validateable {

    public static final emailRegex = "^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+\$"

    UserCommand(def requestParams) {
        email = requestParams.email
        password = requestParams.password
        username = requestParams.username
        age = requestParams.age
    }

    static constraints = {
        username blank: false, unique: true
        password size: 5..15, blank: false
        email email: true, blank: false, validator: emailValidator
        age min: 18
    }
    
    static emailValidator = { String value, UserCommand command ->
        if (!value.find(emailRegex)) {
            return "email.invalid" // getting message from message.properties file
        }
    }
}

In the above example, we can add the constraints after implementing the Validateable on the custom class and do the validation logic similar to the domain classes validation.

Now, let's utilize the above command class inside the controller.

UserCommand userCommand = new UserCommand(requestParams)
        if (!userCommand.validate()) {
            Map result = [success: false, errors: []]
            result.errors = getCommandErrors(userCommand)
            render(result as JSON)
            return
        }
def messageSource

public static List getCommandErrors(def command) {
        List errors = []
        command.errors.allErrors.each { ObjectError error ->
            String msg = messageSource.getMessage(error.code, error.arguments, error.defaultMessage)
            errors.add(msg)
        }
        return errors
    }

For more details visit Grails Validation

Share:

Wednesday, July 6, 2022

How to enable CORS in Grails Application

In this tutorial, we are going to learn how to enable the cross-origin resources sharing CORS in a Grail Application.

Introduction:

Cross-origin resource sharing is the way to trust between the two web services or applications. So if the two web services don't satisfy then a CORS issue may arise.

Cors is a mechanism for the web application that controls listening to certain request from other web applications which is not hosted on the same server. It will not grant access to the content from other applications. So, in order to interact between two different web applications, we need to enable the Cors for that particular app.

Enable CORS in Grails Application:

We can enable cors in application.yml as below

grails:
    cors:
        enabled: true

The above configuration enables the cors for all the origins i.e all applications can interact with our application.

Enable Cors for a specific domain:

application.yml

grails:
    cors:
        enabled: true
        allowedOrigins:
            - https://example.com

This will allow the request only for the domain example.com

Enable Cors for specific requests or URLs:

application.yml

grails:
    cors:
        enabled: true
        allowedHeaders:
            - Content-Type
        mappings:
            '[/api/**]':
                allowedOrigins:
                    - https://example.com

This will allow all the requests from URLs that start with /api for example.com domain. Note that the mapping key must be made with bracket notation i.e [/api/**]

For more detail please visit Grails CORS.

Share:

Saturday, July 2, 2022

Error: Could not find or load main class org.grails.cli.GrailsCli

This is a quick tutorial on how we can resolve the issue on the Grails project.

For grails application sometimes we might get the following error

Error: Could not find or load main class org.grails.cli.GrailsCli

This might be due to the removal of some dependencies or libraries from the application. Sometimes, while loading multiple applications from IDE while downloading the library for a particular project other libraries for another project might remove so this kind of error might occurs for that project.

Let's first delete the build folder under the application.

Now, let's refresh the Gradle project. Here we are using IntelliJ Idea, we can refresh the project as below

After refreshing the project it will download the missing dependencies. Then run the application which will resolve the problem.

We can also try cleaning the application.

If we are using the command line then type the following command to clean the application.

grails clean

If we are using the IntelliJ idea then Ctr+Alt+G opens the command window and use the following command.

clean

Now, re-run the app. This will help resolve the issue.

Share:

Wednesday, June 29, 2022

How to use SiftingAppender in Gradle Groovy project

 In this tutorial, we are going to set up the SiftingAppender in our Gradle Groovy project.

Sifting Appender is useful when we want to separate the log files during runtime i.e if we want to separate the log files per thread or per user session basis.

Unfortunately, in the Gradle Groovy project, SiftingAppender is no longer supported since version 1.0.12 as mentioned in Groovy Configuration.

Let's look into the simple example where we are going to configure the SiftingAppender in logback.groovy, where we want to configure the per-user logging mechanism.

import ch.qos.logback.classic.PatternLayout
import ch.qos.logback.classic.sift.MDCBasedDiscriminator
import ch.qos.logback.classic.sift.SiftingAppender

appender("USER_ROLLING", SiftingAppender) {
    discriminator(MDCBasedDiscriminator) {
        key = 'userid'
        defaultValue = 'NONE'
    }
    sift {
        appender("FILE-${userid}", FileAppender) {
            file = "Path-to-log/${userid}.log"
            append = true
            layout(PatternLayout) {
                pattern = "%level %logger - %msg%n"
            }
        }
    }
}
logger("package-to-log",TRACE,['USER_ROLLING'], false)

This is a simple example SiftingAppender configuration; this is derived from logback sifting appender xml configuration.

We are using the Mapped Diagnostic Context for mapping the context user to create a separate file. We can do a similar for the thread as well.

Let's set up the MDC for user, the sample example looks as below.

import groovy.util.logging.Slf4j
import org.slf4j.MDC
@Slf4j
class UserLogging {

    public static void debug(String message, String userid = '') {
        setUserMDC(userid)
        log.debug(message)
    }

    public static void error(String message, String userid = '') {
        setUserMDC(userid)
        log.error(message)
    }

    public static void info(String message, String userid = '') {
        setUserMDC(userid)
        log.info(message)
    }

    public static void setUserMDC(String userid) {
        try {
            if (!userid) {
                MDC.remove("userid")
                return
            }
            MDC.put("userid", userid)
        }catch(e) {
            log.error("Error setting user Mapped Diagnostic Context due to "+e.getMessage())
        }
    }
}

Here, if the userid is available then we are setting the MDC for userid so the log file can be written in a separate file per user. If you want to do with request user do the similar in filter class or the place where it suits.

Now, if we run the application we will get the error as a result the appender doesn't work. So, here we found the solution project that extends Logback Gaffer so that SiftingAppender can be configured in Groovy DSL from this Github repo.

Simply download the jar file for that project and add it to the application.

For the Gradle project create a libs directory under the project directory and load and compile from build.gradle file.

Under build.gradle under dependencies{} section:

compile fileTree(dir: 'libs', include: '*.jar')

If we run the application it suppose to work. The log file will be created on the respective file path.

Share:

Saturday, December 18, 2021

How to change Grails App server port in application.yml

This is a quick tutorial on how to set server port while running grails application. By default, grails will use the embedded tomcat server running on port 8080.

Sometimes if another process is using port 8080 then we might get a port address already in use error.

So, what we will do is to change the default port in the config. In grails 3.x version we can set up the custom port inside application.yml file.

Inside application.yml file lets add the following config setup to override the default port 8080.
server:
    port : "8090"
Now if we run the application, it will run on port 8090. 

If we want to configure the setup within the environment then we can do as below:
environments:
    development:
        server:
            port : "8090"
This will set the server port only for the development environment. Re-run the application.
Share:

Sunday, November 21, 2021

Error occurred running Grails CLI: No profile found for name [web]. (Use --stacktrace to see the full trace)

In grails application, the error mentioned below might occur.

 

Error |
Error occurred running Grails CLI: No profile found for name [web]. (Use --stacktrace to see the full trace)

Process finished with exit code 1
This might be of different reason. Let's try to fix it by deleting the build folder under the application and re-run the application. 

This might work in most cases if this doesn't help then try to clean the app. 

If you are using the command line then type the following command to clean the application.
grails clean
if you are using the IntelliJ idea then Ctr+Alt+G opens the command window and use the following command.
clean
Now, re-run the app.
Share: