Posts

Showing posts from October, 2018

Overwriting Spring Security Context through Filter

overwriting-spring-security-context-through-filter This article presents a strategy that overwrites the spring security context in order to allow a user to visit the resources without authenticating the user through the authentication filters. It is very common that in a single-sign-on application to use a session store to persist the session information after the user has successfully signed in. Spring Session magically takes care this for us if we add @enableXxxHttpSession to the application configuration. While it is convenient to use an out-of-the-box solution, it is extremely helpful to implement one so each fundamental part of this pattern can be fully understood. This insight can improve the efficiency of the code by way of a more optimal choice of scope for any session store, even to make a home-made one. We will create a javax.servlet.Filter implementation so we could add this filter as part of the security filter chain. The place this filter should

Spring Data MongoDB GridFS 3.4

spring-data-mongodb-gridfs-3-4 This article shows a typical usage of MongoDB GridFS with Spring Data MongoDB. This is for MongoDB java driver v3.4 and Spring Data MongoDB v1.10.x. Note that Spring Data MongoDB v2.X introduces breaking changes with the MongoDB java driver 3.6+. This article only shows the usage of the v3.4 driver with Spring Data MongoDB v1.10.x. FileService Interface public interface FileService { GridFSDBFile find ( String id ) ; Optional < GridFsResource > findAsResource ( String id ) ; String store ( String name , MultipartFile file ) ; void delete ( String id ) ; } FileService Implementation We can’t use GridFsTemplate.getResource(String location) here to get the resource because there might be files with the same name. To find the expected file, we need to find a list of the resources that all match the same filename and then filter them by the id after retrieving all the files. This is acceptable because

Handle Non-encoded Request URL

handle-non-encoded-request-url Normally we need to encode the request URL from the client before sending a request to the server, but there may be just one time that you really can’t enforce the client to encode their request URL and sometimes it contains special characters that will make the server mark them as illegal characters in the request. This article shows an example of how to use a filter to preprocess the request on the server side. Bad URL If you copy and paste the following URL that takes an query parameter as input and the value as {"inputInfo":{"inputText":"5.00%"}} - a JSON literal that contains a special character % . Your server will most likely complain and throw an exception on this illegal character. http://localhost:8090/extract?input={"inputInfo":{"inputText":"5.00%"}} What could be done to solve this problem from the server side? use Spring preprocessor bean to preprocess

Tomcat Invalid Character in Request

tomcat-invalid-character-in-request 8.5 Tomcat throws an IllegalArgumentException when processing request URL that has non-encoded illegal special characters. This article shows two workarounds. Note It is always better to follow the standard to encode URL at the client side first to prevent this problem from happening at all. Error Log 2018-10-10 19:29:55.522 INFO 21872 — [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level. java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986 Solution 1 Downgrade Tomcat to 8.0 or use another web container Solution 2 Spring boot 1.x You could use simply swap out the embedded tomcat with a 8.0 version. < properties > < tomcat.version > 8.0.47 </ tomcat.version > </ properties

Spring Data Repository Query Precedence Tricks

spring-data-repository-query-precedence-tricks Spring Data repository method is very handy but it also comes with its limitation, especially when composed with condition precedence. This article shows one way to work with it and its caveats. Use Case Given the following type: @Entity public class Book { @Id private Long id ; private String title ; private String edition ; // Getters and Setters ... } 1. check if there is any book whose title or edition matches the specified. This one is easy to come up with. We could simply use the keyword Or to compose the query: boolean existsByTitleOrEdition ( String title , String edition ) ; 2. check if there is any book whose title or edition matches the specified and is not itself. This one looks just as easy as the first one, we could have just added another condition and compose with the keyword And : boolean existsByTitleOrEditionAndIdIsNot ( String title , String edi

Entity Graphs for Lazy Loading

entity-graphs-for-lazy-loading Entity Graphs are templates for persistence query. One common problem it solves is Lazy Loading . This article introduces the basics of Entity Graphs and how to use Entity Graphs with JPA and Spring Data to solve the Lazy Loading . 1. Entity Graph Basics The tutorial will be using the Order class as a persistence entity. @Entity public class Order implements Serializable { @Id private String id ; private LocalDateTime datetime ; @ManyToOne ( fetch = EAGER ) private User user ; @OneToMany ( fetch = LAZY ) private List < Item > items ; @OneToMany ( fetch = LAZY ) private List < Payment > payments ; } All fields in an entity are lazily fetched by default, so the default entity graph consists of only the fields whose FetchType is EAGER . The exceptions are that the primary key and version fields of an entity class are always fetched. In the above exam

PostgreSQL and Hibernate CLOB

postgresql-and-hibernate-clob When you need a SQL data type that can hold more than 255 characters, you are likely to use some large character data type such as CLOB, BLOB. It is easy to find the right type if you know what exactly the database you will stick to. However, when we use Hibernate, it provides the annotations that support the cross-platform data type translation. Story I like to use H2 embedded database as a starting point when I start a new project, but later on, when I switch to use PostgreSQL, I was prompted org.postgresql.jdbc.PgConnection.createClob() is not yet implemented . I have one property in my class is a String type, as I marked as @Lob and wish Hibernate will take care of the rest for me, but NO. I still get the same exception. Solution To solve this, I need to add the additional @Type(org.hibernate.type.TextType) annotation to the property as well, and then it works nicely with PostgreSQL in addition to H2. Lesson Learnt org.h

Entity Mapping with Inheritance in Hibernate

entity-mapping-with-inheritance-in-hibernate Inheritance could be enabled in Hibernate with the @MappedSuperclass annotation. This annotation could greatly reduce the boilerplate in our entity mapping. Story Using inheritance to map a paper-book and audio-book type of data. Solution The following Resource class uses @MappedSuperclass annotation to abstract the shared properties into a superclass that represents a resource that could be extended by all concrete resources. In this case, we also make the resource generic so that each the primary key property id could be flexible with the type of its subclass. By using the @MappedSuperclass instead of the @Entity annotation on the superclass, it tells Hibernate to create these superclass properties in each of the respective subclass tables in the database. @MappedSuperclass public class Resource < T > { @Id @GeneratedValue ( strategy = AUTO ) private T id ; @Column ( length

Exception Handling in WebMethods

Image
exception-handling-in-webmethods Try-Catch block is commonly used to try a risky operation and catch the exception it may raise. This article shows the trick to do the similar thing without writing java code in a flow service with WebMethods. The following flow service sequence is an alternative to a Try-Catch block. Figure 1. Try-Catch Sequence in WebMethods Sequence The outer sequence exits on success; the first inner sequence exits on failure and the second inner sequence exits on done. A sequence block consists of any number of operations that needs to be executed in the placed order. There are three options available for instructing a sequence to exit - FAILURE (default), SUCCESS and DONE . When a sequence exits, the next closest sibling statement or sequence will be executed unless the enclosing sequence instructs to exit on success. Try Block In the above case, if the risky operation pub.flow:debugLog (first) runs successfully, the SEQUENCE (exi