Asynchronous servlet 3.0 url mapping - servlet-3.0

How to set two Url patterns in Servlets 3.0 through annotation as:
#WebServlet(urlPatterns = "/flow", asyncSupported = true)
public class FlowService extends HttpServlet
This example is for one url pattern but I want to set it for two urls.

urlPatterns = {"/flow", "/low"}

Related

What is the idiomatic Groovy and Grails way of casting to a Domain Model class?

Given the Grails Domain Classes "Apple.groovy" and "Orange.groovy", not strictly related, and the following Grails Service invoked from the Controllers:
package test
import grails.transaction.Transactional
import javax.servlet.http.HttpServletRequest
#Transactional
class UploadService {
def uploadApple(HttpServletRequest request, Apple o) {
def file = request.getFile('payload')
o.payload = file.getBytes()
o.filename = file.originalFilename
o.contentType = file.contentType
o.save(flush:true)
}
def uploadOrange(HttpServletRequest request, Orange o) {
def file = request.getFile('payload')
o.payload = file.getBytes()
o.filename = file.originalFilename
o.contentType = file.contentType
o.save(flush:true)
}
}
How would one go about unifying this code under a common method? I was hoping Groovy's optional types would handle this for me, but I can't seem to be able invoke .save() successfully if I remove the types from the method signature.
Thanks in advance
Avoid passing request to service and pass File to service. Did you try it this way?
def upload(file, obj) {
obj.payload = file.getBytes()
obj.filename = file.originalFilename
obj.contentType = file.contentType
obj.save(flush:true)
}
Unlike Java, Groovy does duck typing. Typing is concerned with assigning a type to any object. Duck typing is concerned with establishing the suitability of an object for some purpose.
Now you have to be careful because this will not work for every object. The reason that it works for Apple and Orange is because both have exactly the same set of attributes and attribute types.
One would wonder, why you would have two different domain that behave exactly the same, but that's obviously is a different discussion.
In Grails 3, domain classes implement the GormEntity trait, which is where the save() method comes from. But that doesn't solve the issue with the payload, filename, and contentType properties.
What you can do is create an interface which declares the methods and properties common to both domain classes and also implements org.grails.datastore.gorm.GormEntity. Then, have the domain classes implement the interface:
interface Uploadable extends GormEntity {
byte [] payload
String filename
String contentType
}
class Apple implements Uploadable {
byte [] payload
String filename
String contentType
}
Then, you can use the interface in your service.
#Transactional
class UploadService {
def upload(HttpServletRequest request, Uploadable o) {
def file = request.getFile('payload')
o.payload = file.getBytes()
o.filename = file.originalFilename
o.contentType = file.contentType
o.save(flush:true)
}
}
Note: Since Grails injects the GormEntity trait into the domain classes automatically, I don't know what happens if you use it explicitly as shown.

Inherit a class with private constructor? Or create a new module?

I'm using the Http type of FSharpData.
type Http private() =
......
static member Request(url, ?query, ?headers, ?meth, ?body, ?cookies, ?cookieContainer, ?certificate) =
......
However, I need to extend static memeber Request to handle cookies. I cannot inherit the class since its constructor is private.
type Web () =
inherit Http() // Error
override Request
let ObSSOCookie = new Cookie()
......
Or I had to create a module with functions that call the static member functions? Can the module has the same name of Http?
The Http type is a static class, because it's stateless, so it doesn't make sense to inherit from it. If you want to use cookies and maintain them across requests, you can just create a CookieContainer and reuse it across requests:
let cc = CookieContainer()
Http.RequestString("url1", cookieContainer = cc)
Http.RequestString("url2", cookieContainer = cc)
If you really want to, you can create a wrapper for it like this:
type HttpWithState() =
let cookies = CookieContainer()
static member RequestString(url, ?params, ?headers, ...) =
Http.RequestString(url, ?params = params, ?headers = headers, ..., cookieContainer = cookies)
and then use it like this:
let http = HttpWithState()
http.RequestString("url1")
http.RequestString("url2")
But you won't gain that much over using the Http type directly
I don't believe that you can inherit from this class - this is probably a design desicision.
However, the full path to that type is
FSharp.Net.Http
so you could create your own type in something like
A.B.Http
which could call the original http functions and provide overrides through that method.
You can try adding static extension method to Http class, if it doesn't need to access privates:
type FSharp.Net.Http with
static member RequestWithCookies(...) = ...

Create custom Validator

How should I create and configure a validator class to use it as a domain class constraint? For example:
class Link {
String url
static constraints = { url url:true }
}
Motivation: Grails UrlValidator does not allow underline character despite it being valid, see rfc2396, section 2.3. Unreserved Characters.
You can have a utility class in src/groovy with required validators (as static properties) and refer them in the concerned domain class.
//src/groovy
class MyValidators{
static urlCheck = {url, obj ->
//custom validation for url goes here.
}
}
class Link {
String url
static constraints = {
url validator: MyValidators.urlCheck
}
}
If there is no need to externalize the validator to a separate utility class then you can directly use the validator in domain class as:
static constraints = {
url validator: {value, obj -> ...}
}

Cannot use grails g.link in domain class

I have static method in a domain class that returns a url. I need to build that url dynamically but g.link isn't working.
static Map options() {
// ...
def url = g.link( controller: "Foo", action: "bar" )
// ...
}
I get the following errors:
Apparent variable 'g' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes:
You attempted to reference a variable in the binding or an instance variable from a static context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method 'g' but left out brackets in a place not allowed by the grammar.
# line 17, column 19.
def url = g.link( controller: "Foo", action: "bar" )
^
1 error
Obviously my problem is that I am trying to access g from static context, so how do I get around this?
The g object is a taglib, which is not available inside a domain class like it would be in a controller. You can get at it through the grailsApplication as shown here: How To Call A Taglib As A Function In A Domain Class
A better way to do this in Grails 2+ is through the grailsLinkGenerator service, like so:
def grailsLinkGenerator
def someMethod() {
def url = grailsLinkGenerator.link(controller: 'foo', action: 'bar')
}
In both cases, you'll need to do some extra work to get grailsApplication/grailsLinkGenerator from a static context. The best way is probably to grab it off the domainClass property of your domain class:
def grailsApplication = new MyDomain().domainClass.grailsApplication
def grailsLinkGenerator = new MyDomain().domainClass.grailsApplication.mainContext.grailsLinkGenerator
If you're using Grails 2.x you can use the LinkGenerator API. Here's an example, I am re-using a domain class I was testing with earlier so ignore the non-url related functionality.
class Parent {
String pName
static hasMany = [children:Child]
static constraints = {
}
static transients = ['grailsLinkGenerator']
static Map options() {
def linkGen = ContextUtil.getLinkGenerator();
return ['url':linkGen.link(controller: 'test', action: 'index')]
}
}
Utility Class with Static Method
#Singleton
class ContextUtil implements ApplicationContextAware {
private ApplicationContext context
void setApplicationContext(ApplicationContext context) {
this.context = context
}
static LinkGenerator getLinkGenerator() {
getInstance().context.getBean("grailsLinkGenerator")
}
}
Bean Def for New Utility Bean
beans = {
contextUtil(ContextUtil) { bean ->
bean.factoryMethod = 'getInstance'
}
}
If you need the base URL, add absolute:true to the link call.

Grails UrlMappings for unknown number of variables

I'm using url mappings to translate the URL directory structure into categories within a site, currently using:
class UrlMappings {
static excludes = ['/css/*','/images/*', '/js/*', '/favicon.ico']
static mappings = {
"/$category1?/$category2?/$category3?/"(controller: 'category')
"500"(view:'/error')
"404"(view:'/notFound')
}
}
At present this supports categories three levels deep. I'd like to be able to support categories N levels deep where N >= 1.
How can this be achieved?
The asterisk, either single or double, is used for wilcard url mapping.
A single asterisk will match anything at the given level:
static mappings = {
"/images/*.jpg"(controller:"image")
}
// Matches /images/logo.jpg, images/header.jpg and so on
A double asterisk will match anything on more than one level:
static mappings = {
"/images/**.jpg"(controller:"image")
}
// Matches /images/logo.jpg, /images/other/item.jpg and so on
Combined with the ? for optional mapping matches, the following will work in the context of the question:
class UrlMappings {
static excludes = ['/css/*','/images/*', '/js/*', '/favicon.ico', '/WEB-INF/*']
static mappings = {
"/**?"(controller: 'category')
"500"(view:'/error')
"404"(view:'/notFound')
}
}
This question is ancient but in the url mappings you can also do this
"/categories/$categories**?"(controller:categories)
this will load the rest of the uri into param variable
/categories/animals/dogs/retrievers
///goes to categories controller and has...
params.categories //= "animals/dogs/retrievers"
You could then use that to do various dynamic things

Resources