Posts

Showing posts from October, 2018

Overwriting Spring Security Context through Filter

overwriting-spring-security-context-through-filterThis 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 be inserted is before the Sec…

Spring Data MongoDB GridFS 3.4

spring-data-mongodb-gridfs-3-4This 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 InterfacepublicinterfaceFileService{ GridFSDBFile find(String id); Optional<GridFsResource>findAsResource(String id); String store(String name, MultipartFile file);voiddelete(String id);}FileService ImplementationWe 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 at that point, the InputStream hasn’t been requested yet. GridFsTemplate…

Handle Non-encoded Request URL

handle-non-encoded-request-urlNormally 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 URLIf 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 the requestuse Spring AspectJ to p…

Tomcat Invalid Character in Request

tomcat-invalid-character-in-request8.5 Tomcat throws an IllegalArgumentException when processing request URL that has non-encoded illegal special characters. This article shows two workarounds.NoteIt is always better to follow the standard to encode URL at the client side first to prevent this problem from happening at all.Error Log2018-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 3986Solution 1Downgrade Tomcat to 8.0 or use another web containerSolution 2Spring boot 1.xYou could use simply swap out the embedded tomcat with a 8.0 version.<properties><tomcat.version>8.0.47</tomcat.version></properties><dependencies> ... <dependency><groupId…

Spring Data Repository Query Precedence Tricks

spring-data-repository-query-precedence-tricksSpring 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 CaseGiven the following type:@EntitypublicclassBook{@Idprivate 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:booleanexistsByTitleOrEdition(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:booleanexistsByTitleOrEditionAndIdIsNot( String title, String edition, Long id);Is that so?When this method name is translated to SQL, it reads surprisingly astest if an…

Entity Graphs for Lazy Loading

entity-graphs-for-lazy-loadingEntity 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 BasicsThe tutorial will be using the Order class as a persistence entity.@EntitypublicclassOrderimplementsSerializable{@Idprivate 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 example, only id and user will be in the default entity graph.1.1 Fetch GraphsA fetch graph consists of only the fields explicitly specified in the Ent…

PostgreSQL and Hibernate CLOB

postgresql-and-hibernate-clobWhen 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.StoryI 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.SolutionTo 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 Learntorg.hibernate.type.TextType - A type that map…

Entity Mapping with Inheritance in Hibernate

entity-mapping-with-inheritance-in-hibernateInheritance could be enabled in Hibernate with the @MappedSuperclass annotation. This annotation could greatly reduce the boilerplate in our entity mapping.StoryUsing inheritance to map a paper-book and audio-book type of data.SolutionThe 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.@MappedSuperclasspublicclassResource<T>{@Id@GeneratedValue(strategy = AUTO)private T id;@Column(length=255)private String name;// getters and setters are omitted for brevity}@Entitypubli…

Exception Handling in WebMethods

Image
exception-handling-in-webmethodsTry-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 WebMethodsSequenceThe 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 BlockIn the above case, if the risky operation pub.flow:debugLog (first) runs successfully, the SEQUENCE (exit on failure) will exit until the last sta…