mscharhag, Programming and Stuff;

A blog about programming and software development topics, mostly focused on Java technologies including Java EE, Spring and Grails.

  • Monday, 29 February, 2016

    Converting Markdown to PDF or DOCX with Pandoc

    Markdown is a popular text formatting syntax among developers these days. Popular Sites like Github or Bitbucket use Markdown for project documentation and various other types of user generated content. These sites automatically convert markdown syntax to HTML, so it can be displayed in a browser.

    However, maybe you want to use Markdown as document format without using a platform that does the conversion for you. Or you are in need of an output format other than HTML. In this case you need a tool that can convert markdown to the desired target format. Pandoc is is a document conversion tool that can be used for exactly this (and a lot of other things). With Pandoc you can convert Markdown documents to PDF, HTML, Words DOCX or many other formats.

    After installing Pandoc, you can simply run it from command line.

    Note: By default, Pandoc uses LaTeX to generate PDF documents. So, if you want to generate PDF documents, you need to install a LaTex processor first (list of required LaTeX packages).

    To convert a doc.md Markdown file into a PDF document, the following command can be used:

    pandoc -s -o doc.pdf doc.md

    Pandoc is able to merge multiple Markdown files into a single PDF document. To generate a single PDF document out of two Markdown files you can use:

    pandoc -s -o doc.pdf part01.md part02.md

    By default the page margins in the resulting PDF document are quite large. You can change this by passing a margin parameter:

    pandoc -s -V geometry:margin=1in -o documentation.pdf part01.md part02.md

    To create HTML or DOCX documents you simply have to change the file extension of the target file:

    pandoc -s -o doc.html part01.md part02.md
    pandoc -s -o doc.docx part01.md part02.md
    

    The resulting documents are well formatted. The following two screenshot show a DOCX and a PDF document created out of two small example markdown files:

    Resulting DOCX document:

    Word docx document generated by Pandoc

    Resulting PDF document:

    Pdf document generated by Pandoc

     

  • Monday, 22 February, 2016

    Java EE 8 MVC: Working with form parameters

    In the previous two posts we saw how to work with query and path parameters in the upcoming Java EE MVC framework. This post focuses on form parameters.

    When you submit a web form using a post request, the form values are send as part of the request body. The media type (or content type) defines the format that is used to store the values inside the request body. Web forms usually use the media type application/x-www-form-urlencoded. Parameters that are send using this media type can be accessed using the @FormParam annotation.

    Using form parameters

    Assume we have the following simple HTML form, containing two text input fields and a select menu:

    <form action="submit" method="post">
      <label>ID:</label>
      <input type="text" name="id" />
      
      <label>Name:</label>
      <input type="text" name="name" />
      
      <label>Role:</label>
      <select name="role">
        <option value="admin">Admin</option>
        <option value="reporter">Reporter</option>
        <option value="accountant">Accountant</option>
      </select>
      
      <input type="submit" />
    </form>
    

    To process the form values we can use the following controller method:

    public enum Role {
      admin, reporter, accountant
    }
    
    @Controller
    @Path("form-params")
    public class FormParamsController {
    
      @POST
      @Path("submit")
      public String submitParams(
          @FormParam("id") long id,
          @FormParam("name") String name,
          @FormParam("role") Role role) {
    
        ...
      }
    }
    

    With @FormParam form parameters can automatically be mapped to method arguments. Form parameters use the same type conversion rules as query or path parameters (described here). This makes it easy to convert form parameters to primitives, enums or objects.

    Using @FormParam on fields and methods

    Like other parameter annotations @FormParam can be used to annotate fields and methods.

    For example:

    @Controller
    @Path("form-params-fields")
    public class FormParamsFieldController {
    
      @FormParam("id")
      private long id;
    
      @FormParam("role")
      private Role role;
    
      private String name;
    
      @FormParam("name")
      public void setNameField(String name) {
        this.name = name;
      }
    
      @POST
      public String submitParams() {
         // use id, role, name
      }
    }
    

    In this example the submitted form parameters are mapped to fields (id, role) and a setter (setNameField()). Inside submitParams() we can then simply access the fields to obtain the form parameters.

    Quick Summary

    Parameters submitted via HTML forms can be obtained with @FormParam. Like @QueryParam and @PathParam it is possible to annotate fields, methods and method parameters with @FormParam.

    You can find the source code for all examples on GitHub.

  • Sunday, 31 January, 2016

    Java EE 8 MVC: Working with Path Parameters

    In the previous post we saw how to work with query parameters in Java EE MVC. This post continues with a very similar topic: path parameters.

    Path parameters are a dynamic part of the request path and can be specified with the @Path annotation.

    For example:

    @Controller
    @Path("path-params")
    public class PathParamsController {
    
      @GET
      @Path("/date/{year}/{month}")
      public String pathParamDate(@PathParam("year") int year, @PathParam("month") int month) {
        ...
      }
    }
    

    Paths parameter are surrounded with curly brackets inside the @Path annotation. In this example two path parameters are defined: year and month.

    With @PathParam path parameters can be mapped to method parameters.

    We can call this method by sending a request to

    /path-params/date/2016/01
    

    In this case 2016 and 1 will be passed as year and month arguments.

    Type conversion

    Path parameters use the same type conversion rules as query parameters (explained in the previous blog post).

    For example, we can convert a path parameter to an enum value like this:

    public enum Role {
      admin, reporter, accountant
    }
    
    @Controller
    @Path("path-params")
    public class PathParamsController {
    
      @GET
      @Path("/roles/{role}")
      public String pathParamUsers(@PathParam("role") Role role) {
        ...
      }
    }
    

    If we now send a request to

    /path-params/roles/admin
    

    the string admin gets converted to the corresponding enum constant.

    Using @PathParam on fields and methods

    Like @QueryParam the usage of @PathParam is not limited to method parameters. It is also possible to annotate fields or setters with @PathParam.

    For example:

    @Controller
    @Path("path-params")
    public class PathParamsController {
    
      @PathParam("category")
      private String category;
    
      @GET
      @Path("/categories/{category}")
      public String findByCategory() {
        // work with category
      }
    }

    Using Path Parameters with Patterns

    It is possible to define a more specific pattern for a path variable. Therefore, a regular expression can be added after the name of the path variable.

    For example:

    @Controller
    @Path("path-params")
    public class PathParamsController {
    
      @GET
      @Path("/users/{id : \\d+}")
      public String findUserById(@PathParam("id") long id) {
        ...
      }
    
      @GET
      @Path("/users/{name : [a-zA-Z]+}")
      public String findUserByName(@PathParam("name") String name) {
        ...
      }  
    }
    

    Here we define two controller methods that listen on /users/{variable}:

    • findUserById() is only called if a numeric id is part of the request path
    • findUserByName() is used if the path parameter matches the regular expression [a-zA-Z]+.

    So if we send a request to

    /path-params/users/123
    

    findUserById() will be called and 123 is passed as id.

    Sending a request to

    /path-params/users/john
    

    calls findUserByName() and passes john as name.

    Quick Summary

    @PathParam can be used to extract path parameters defined with @Path. Like @QueryParam, @PathParam can be used on method arguments, instance fields and methods.

    When defining path parameters with @Path, a regular expression can be used to define a specific path pattern.

    You can find the source code for all shown examples on GitHub.

  • Thursday, 14 January, 2016

    Java EE 8 MVC: Working with query parameters

    In the previous post about the new Java EE MVC Framework we had a detailed look on Controllers. In this and the following posts we will see how to access various types of request data in MVC Controllers.

    Java EE MVC makes heavy use of JAX-RS and most of the things we will see in this and the next posts are JAX-RS features. So, if you are familiar with JAX-RS you probably will not learn much new in this post.

    Query parameters

    This post focuses on query parameters. If you read my Java EE MVC Getting started post you might already know the @QueryParam annotation. The most common use case of  @QueryParam is to map a query parameter to a controller method parameter.

    For example:

    @Controller
    @Path("query-params")
    public class QueryParamsController {
    
      @GET
      public String queryParams(@QueryParam("name") String name) {
        ...
      }
    }
    

    If we now send a HTTP GET request to

    /query-params?name=john
    

    the string "john" will be passed as name parameter to the method queryParams().

    Type conversion

    With @QueryParam query parameters can automatically be converted to various types.

    For example:

    public enum Role {
      admin, reporter, accountant
    }
    
    @Controller
    @Path("query-params")
    public class QueryParamsController {
    
      @GET
      public String queryParams(
          @QueryParam("id") long id,
          @QueryParam("name") String name,
          @QueryParam("role") Role role) {
    
        ...
      }
    }
    

    We can now send a request like this:

    /query-params?id=42&name=john&role=admin
    

    A query parameter can automatically converted to a type, if the target type matches one of the following rules:

    • It is a primitive type
    • The type has a constructor that accepts a single String argument
    • The type has a static factory method named valueOf() or fromString() with a single String argument
    • The type is List<T>, Set<T>; or SortedSet<T> where T matches one of the previous rules

    In the previous example, the query parameter id is automatically converted to long. If the id parameter is missing or a conversion to long is not possible, an exception will be thrown. It is also possible to use Long instead of long. In this case, we get null passed to the controller method if the id parameter is missing.

    Enums have a valueOf() method by default. So, the query parameter role can automatically be converted to the corresponding enum value.

    Using @QueryParam on fields and methods

    @QueryParam is not limited to method parameters. It is also possible to map query parameters to fields or methods, like the following example shows:

    @Controller
    @Path("query-params-fields")
    public class QueryParamsFieldController {
    
      @QueryParam("id")
      private Long id;
    
      @QueryParam("role")
      private Role role;
    
      private String name;
    
      @QueryParam("name")
      public void setName(String name) {
        this.name = name;
      }
      
      @GET
      public String queryParams() {
        // use id, role and name
      }
    }
    

    If we now send a HTTP GET request to

    /query-params-fields?name=john&id=42&role=reporter
    

    the parameters are set to the fields id, role and name (via setName()) before queryParams() is called.

    Do not forget that a new instance of the class is created for every request, so it is safe to have fields that contain request information.

    Quick Summary

    The @QueryParam annotation can be used to obtain query parameters. @QueryParam can be used on fields, methods and method parameters. Query parameters can be automatically converted to various types, as long as the target type is a primitive type, contains a String constructor or contains valueOf() or fromString() factory methods.

    You can find the source code for all the shown examples on GitHub.

    In the next post we will see how to work with path parameters.

  • Sunday, 4 October, 2015

    Java EE 8 MVC: A detailed look at Controllers

    Java EE MVC is a new action based MVC framework planned for Java EE 8 and specified in JSR-371. This is the second post of my Java EE 8 MVC tutorial. The first post covered the basics and shows how to get started with Ozark, the Java EE 8 MVC reference implementation.

    In this post we will have a more detailed look at MVC Controllers.

    MVC Controllers

    A controller is responsible for processing incoming requests. It invokes business logic, updates the model and returns the view that should be rendered. An MVC Controller is a JAX-RS resource method annotated with @Controller. If a class is annotated with @Controller, then all resource methods of this class are regarded as controllers.

    The following example shows a simple Controller that renders a product details page for a given product id:

    @Path("product")
    @Controller
    public class ProductController {
    
      @Inject
      private Models models;
    
      @Inject
      private ProductService productService;
    
      @GET
      public String getProductDetailPage(@QueryParam("id") long productId) {
        Product product = this.productService.getProduct(productId);
        models.put("product", product);
        return "/WEB-INF/jsp/productDetailPage.jsp";
      }
    }

    This Controller resolves a product id (passed as id request parameter) to a product using a ProductService. The obtained product is added to the model and a path to a view is returned. The view is then rendered with the information stored in the model.

    Like in JAX-RS, the @Path annotation is used to define the URL path. This Controller is accessible via a URL that looks like this:

    /<application-path>/product?id=42

    The following example shows a hybrid class with one MVC controller method and one traditional JAX-RS resource method:

    @Path("hybrid")
    public class HybridController {
    
      @GET
      @Path("jaxrs")
      public Response jaxrs() {
        return Response.status(200).build();
      }
    
      @Path("mvc")
      @GET
      @Controller
      public String mvc() {
        return "/WEB-INF/jsp/hello.jsp";
      }
    }

    Controller methods work very similar to JAX-RS resource methods. However, there are two small differences:

    • A return type of String on Controller methods is interpreted as a view path. With JAX-RS resource methods the returned String is interpreted as text content.
    • The default response media type for Controller methods is text/html. Like in JAX-RS the media type can be changed using the @Produces annotation.

    MVC Controller classes and hybrid classes with MVC Controller methods need to be CDI-managed beans. Like JAX-RS resource classes, MVC controller classes are instantiated per request. For every request, a new Controller class instance is created.

    Like in JAX-RS the supported HTTP verb is defined by annotations. If a controller method should listen for HTTP POST requests, it needs to be annotated with @POST instead of @Get.

    For example:

    @Controller
    @Path("http")
    public class PostController {
    
      @POST
      @Path("post")
      public String post() {
        return "/WEB-INF/jsp/hello.jsp";
      }
    }

    Controller return types

    Four different return types are supported on MVC controller methods:

    • String - The returned string value is interpreted as view path.
    • void - In this case the view need to be defined using the @View annotation
    • Viewable - An abstraction that includes information about a view, the model and the used view engine.
    • Response - A JAX-RS response. The entity type of the response needs to be String, void or Viewable.

    The following class defines four controller methods using different return types. All methods return the same response:

    @Controller
    @Path("return-types")
    public class ReturnTypesController {
    
      @GET
      @View("/WEB-INF/jsp/hello.jsp")
      @Path("return-void")
      public void returnVoid() {
      }
    
      @GET
      @Path("return-string")
      public String returnString() {
        return "/WEB-INF/jsp/hello.jsp";
      }
    
      @GET
      @Path("return-string")
      public Viewable returnViewable() {
        return new Viewable("/WEB-INF/jsp/hello.jsp");
      }
    
      @GET
      @Path("return-response")
      public Response returnResponse() {
        return Response.status(Response.Status.OK)
            .entity("/WEB-INF/jsp/hello.jsp")
            .build();
      }
    }

    Returning a JAX-RS Response is the most flexible way. This way the JAX-RS Response builder can be used to modify the HTTP status code, response headers and more.

    If void is used as return type, the view needs to be defined using the @View annotation. @View can be applied to methods (like in the previous example) and classes. If a class is annotated with @View, the view is applied to all controller methods in this class. A class level @View annotation can be overridden by a more specific view definition on method level, like shown in the following example:

    @Controller
    @Path("views")
    @View("/WEB-INF/jsp/foo.jsp")
    public class ViewController {
    
      @GET
      @Path("first")
      public void first() {
        // renders foo.jsp
      }
    
      @GET
      @Path("second")
      @View("/WEB-INF/jsp/bar.jsp")
      public void second() {
        // renders bar.jsp
      }
    
      @GET
      @Path("third")
      public String third() {
        // renders baz.jsp
        return "/WEB-INF/jsp/baz.jsp";
      }
    }

    Summary

    The @Controller annotation can be used on methods and classes. When used on classes, all methods of the class are considered as controllers. Controller methods invoke business logic and determine the view that should be rendered. Classes with Controller methods are CDI managed beans. For every request, a new class instance will be created. Traditional JAX-RS resource methods can be combined with MVC Controller methods in the same class.

    In the next posts about Java EE 8 MVC we will have a look at parameter binding and validation.

    You can find the example source code on GitHub.