Share on TwitterDigg This

Introduction



I don’t get all the hate that new technology adopters have with existing frameworks. It impresses me the number of scala users out there thrashing everything java.

We all know the limitations of java platform. But you have to face it, most of the codebase today is java based. Most of your co-workers are happy with java, and the worst: so is management.

So going on a bang approach and getting rid of all things java, may not be the best approach if you want to use some new cool language like scala. I took this approach, introducing scala in a Spring based rest app. Spring is well known, developers are used it, your manager probably heard something about it :) and its a very stable and tested framework. So you are not adding some 0.0.2 version of a new REST service complete based on scala :)

Enough words, let’s get our hands dirty :)


Setup


If you followed my last post, there’s an example on how to create a HATEOAS based app using Spring there. Here we have lower expectation. All we want is to setup a basic SpringMVC Rest project using Scala.

All the setup is pretty much the same, except for the fact we will be using scala classes instead of java classes here. And a very important step: Jackson will not work as a JSON serializer. You’ll have to use Jerkson


So, to make things simpler here, I’ll just paste all the relevant code bellow, any question, just go to my previous post explaining the role of each of the classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class WebAppInitializer extends WebApplicationInitializer{
 
	def onStartup(container: ServletContext) : Unit = {
	  val rootContext = new AnnotationConfigWebApplicationContext()
	  rootContext.register(classOf[AppConfig])
	  container.addListener(new ContextLoaderListener(rootContext));
	  val dispatcherContext  = new AnnotationConfigWebApplicationContext()
	  dispatcherContext.register(classOf[DispatcherConfig])
	  val dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext))
	  dispatcher.setLoadOnStartup(1)
	  dispatcher.addMapping("/")
	}
}
 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages=Array("com.fb.mcare.controllers"))
class DispatcherConfig extends WebMvcConfigurerAdapter {
 
	@Bean
	def handleMapping() : DefaultAnnotationHandlerMapping  = {
		new DefaultAnnotationHandlerMapping
	}
 
	@Override
	override def configureMessageConverters(converters: java.util.List[HttpMessageConverter[_]]) {
		val converter = new MappingJerksonHttpMessageConverter(MediaType.APPLICATION_JSON)
		converters.add(converter)
	}
 
}
 
 
@Controller
@Autowired
@RequestMapping(Array("/patients/*"))
class PatientController(val service:PatientService) {
 
  def this() = {
    this(null)
  }
 
  @RequestMapping(produces=Array("application/json"), method=Array(RequestMethod.GET), value=Array("/{id}"))
  def list(@PathVariable id : String) : ResponseEntity[Person] = {
    println(id)
	val p = new Person("vinicius",32)
	val entity = new ResponseEntity[Person](p,HttpStatus.OK)
	return entity
  }
 
}

Ok so things start to get interesting here on line 25, were we actually setup our JerksonMapping.

Lines 34-51 represent our controller, note that we are using regular Spring annotations, and being a good scala class, we inject the PatientService in our controller, making it a immutable val :)

Note, that you can do pretty much everything you’d do with a regular spring controller, but this time you have the power of scala at your hands.

The most important part is the MappingJerksonMessageConverter. Using this converter instead of Jackson, makes possible the serialization/deserialization of Scala classes into Json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import scala.reflect.Manifest
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.MediaType
import org.springframework.http.HttpInputMessage
import scala.collection.JavaConversions
import com.codahale.jerkson.Json
import java.io.IOException
import org.springframework.http.converter.HttpMessageNotReadableException
import org.springframework.http.HttpOutputMessage
import org.springframework.http.converter.HttpMessageNotWritableException
 
class MappingJerksonHttpMessageConverter(val supportedMediaType: MediaType) extends HttpMessageConverter[Any] {
 
 
  override def canRead(clazz : Class[_], mediaType: MediaType) : Boolean = {
 
    Json.canDeserialize(Manifest.classType(clazz))
  }
 
  override def canWrite(clazz : Class[_], mediaType: MediaType) : Boolean = {
    Json.canSerialize(Manifest.classType(clazz));
  }
 
  override def getSupportedMediaTypes() : java.util.List[MediaType] = {
    JavaConversions.asJavaList(List(supportedMediaType))
  }
 
  @throws(classOf[IOException])
  @throws(classOf[HttpMessageNotReadableException])
  override def read(clazz : Class[_], inputMessage : HttpInputMessage) : AnyRef ={
    Json.parse(inputMessage.getBody())
  } 
 
  @throws(classOf[IOException])
  @throws(classOf[HttpMessageNotWritableException])
  override def write(contentType : AnyRef, mediaType: MediaType, outputMessage: HttpOutputMessage) : Unit ={
    Json.generate(contentType,outputMessage.getBody())
  }
}

And that’s it :) You can now start using Spring with your scala project, and maybe even fool your manager (should not be a hard task anyways) that you are using Spring (but with the scala language power under the hood).

Happy coding!

Leave a Reply

You must be logged in to post a comment.