Quantcast
Channel: Baeldung
Viewing all 3450 articles
Browse latest View live

Jackson – Bidirectional Relationships

$
0
0

1. Overview

In this tutorial we’ll go over the best ways to deal with bidirectional relationships in Jackson.

We’ll discuss the Jackson JSON infinite recursion problem, then – we’ll see how to serialize entities with bidirectional relationships and finally – we will deserialize them.

2. Jackson Infinite Recursion

First – let’s take a look at the Jackson infinite recursion problem. In the following example we have two entities – “User” and “Item” – with a simple one-to-many relationship:

The “User” entity:

public class User {
    public int id;
    public String name;
    public List<Item> userItems;
}

The “Item” entity:

public class Item {
    public int id;
    public String itemName;
    public User owner;
}

When we try to serialize an instance of “Item“, Jackson will throw a JsonMappingException exception:

@Test(expected = JsonMappingException.class)
public void givenBidirectionRelation_whenSerializing_thenException()
  throws JsonProcessingException {
    User user = new User(1, "John");
    Item item = new Item(2, "book", user);
    user.addItem(item);

    new ObjectMapper().writeValueAsString(item);
}

The full exception is:

com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (StackOverflowError) 
(through reference chain: 
org.baeldung.jackson.bidirection.Item["owner"]
->org.baeldung.jackson.bidirection.User["userItems"]
->java.util.ArrayList[0]
->org.baeldung.jackson.bidirection.Item["owner"]
->…..

Let’s see, over the course of the next few sections – how to solve this problem.

3. Use @JsonManagedReference, @JsonBackReference

First, let’s annotate the relationship with @JsonManagedReference, @JsonBackReference to allow Jackson to better handle the relation:

Here’s the “User” entity:

public class User {
    public int id;
    public String name;

    @JsonBackReference
    public List<Item> userItems;
}

And the “Item“:

public class Item {
    public int id;
    public String itemName;

    @JsonManagedReference
    public User owner;
}

Let’s now test out the new entities:

@Test
public void givenBidirectionRelation_whenUsingJacksonReferenceAnnotation_thenCorrect()
  throws JsonProcessingException {
    User user = new User(1, "John");
    Item item = new Item(2, "book", user);
    user.addItem(item);

    String result = new ObjectMapper().writeValueAsString(item);

    assertThat(result, containsString("book"));
    assertThat(result, containsString("John"));
    assertThat(result, not(containsString("userItems")));
}

Here is the output of serialization:

{
 "id":2,
 "itemName":"book",
 "owner":
    {
        "id":1,
        "name":"John"
    }
}

Note that:

  • @JsonManagedReference is the forward part of reference – the one that gets serialized normally.
  • @JsonBackReference is the back part of reference – it will be omitted from serialization.

4. Use @JsonIdentityInfo

Now – let’s see how to help with the serialization of entities with bidirectional relationship using @JsonIdentityInfo.

We add the class level annotation to our “User” entity:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class User { ... }

And to the “Item” entity:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Item { ... }

Time for the test:

@Test
public void givenBidirectionRelation_whenUsingJsonIdentityInfo_thenCorrect()
  throws JsonProcessingException {
    User user = new User(1, "John");
    Item item = new Item(2, "book", user);
    user.addItem(item);

    String result = new ObjectMapper().writeValueAsString(item);

    assertThat(result, containsString("book"));
    assertThat(result, containsString("John"));
    assertThat(result, containsString("userItems"));
}

Here is the output of serialization:

{
 "id":2,
 "itemName":"book",
 "owner":
    {
        "id":1,
        "name":"John",
        "userItems":[2]
    }
}

5. Use @JsonIgnore

Alternatively, we can also use the @JsonIgnore annotation to simply ignore one of the sides of the relationship, thus braking the chain.

In the following example – we will prevent the infinite recursion by ignoring the “User” property “userItems” from serialization:

Here is “User” entity:

public class User {
    public int id;
    public String name;

    @JsonIgnore
    public List<Item> userItems;
}

And here is our test:

@Test
public void givenBidirectionRelation_whenUsingJsonIgnore_thenCorrect()
  throws JsonProcessingException {
    User user = new User(1, "John");
    Item item = new Item(2, "book", user);
    user.addItem(item);

    String result = new ObjectMapper().writeValueAsString(item);

    assertThat(result, containsString("book"));
    assertThat(result, containsString("John"));
    assertThat(result, not(containsString("userItems")));
}

And here is the output of serialization:

{
 "id":2,
 "itemName":"book",
 "owner":
    {
        "id":1,
        "name":"John"
    }
}

6. Use a Custom Serializer

Next – let’s see how to serialize entities with bidirectional relationship using a custom serializer.

In the following example – we will use custom serializer to serialize the “User” property “userItems“:

Here’s the “User” entity:

public class User {
    public int id;
    public String name;

    @JsonSerialize(using = CustomListSerializer.class)
    public List<Item> userItems;
}

And here is the “CustomListSerializer“:

public class CustomListSerializer extends JsonSerializer<List<Item>>{

    @Override
    public void serialize(List<Item> items, JsonGenerator generator, SerializerProvider provider) 
      throws IOException, JsonProcessingException {
        List<Integer> ids = new ArrayList<Integer>();
        for (Item item : items) {
            ids.add(item.id);
        }
        generator.writeObject(ids);
    }
}

Let’s now test out the serializer and see the right kind of output being produced:

@Test
public void givenBidirectionRelation_whenUsingCustomSerializer_thenCorrect()
  throws JsonProcessingException {
    User user = new User(1, "John");
    Item item = new Item(2, "book", user);
    user.addItem(item);

    String result = new ObjectMapper().writeValueAsString(item);

    assertThat(result, containsString("book"));
    assertThat(result, containsString("John"));
    assertThat(result, containsString("userItems"));
}

And the final output of the serialization with the custom serializer:

{
 "id":2,
 "itemName":"book",
 "owner":
    {
        "id":1,
        "name":"John",
        "userItems":[2]
    }
}

7. Deserialize with @JsonIdentityInfo

Now – let’s see how to deserialize entities with bidirectional relationship using @JsonIdentityInfo.

Here is the “User” entity:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class User { ... }

And the “Item” entity:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Item { ... }

Let’s now write a quick test – starting with some manual JSON data we want to parse and finishing with the correctly constructed entity:

@Test
public void givenBidirectionRelation_whenDeserializingWithIdentity_thenCorrect() 
  throws JsonProcessingException, IOException {
    String json = 
      "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}";

    ItemWithIdentity item = new ObjectMapper().reader(ItemWithIdentity.class).readValue(json);
    assertEquals(2, item.id);
    assertEquals("book", item.itemName);
    assertEquals("John", item.owner.name);
}

8. Use Custom Deserializer

Finally, let’s deserialize the entities with bidirectional relationship using a custom deserializer.

In the following example – we will use custom deserializer to parse the “User” property “userItems“:

Here is “User” entity:

public class User {
    public int id;
    public String name;

    @JsonDeserialize(using = CustomListDeserializer.class)
    public List<Item> userItems;
}

And here is our “CustomListDeserializer“:

public class CustomListDeserializer extends JsonDeserializer<List<Item>>{

    @Override
    public List<Item> deserialize(JsonParser jsonparser, DeserializationContext context) 
      throws IOException, JsonProcessingException {
        return new ArrayList<Item>();
    }
}

And here is our test:

@Test
public void givenBidirectionRelation_whenUsingCustomDeserializer_thenCorrect()
  throws JsonProcessingException, IOException {
    String json = 
      "{\"id\":2,\"itemName\":\"book\",\"owner\":{\"id\":1,\"name\":\"John\",\"userItems\":[2]}}";

    Item item = new ObjectMapper().reader(Item.class).readValue(json);
    assertEquals(2, item.id);
    assertEquals("book", item.itemName);
    assertEquals("John", item.owner.name);
}

9. Conclusion

We learned how serialize/deserialize entities with bidirectional relationship using Jackson.

You can find the source code here.


Baeldung Weekly Review 1

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Java and Spring

>> Under The Hood With A Prototype of Enhanced Generics for Java

Improvements to Generics coming in Java 10.

Unfortunately it doesn’t look like these improvements go all the way to reifying generics so we’ll still have type erasure, but bringing primitives into play does open up a few interesting possibilities.

>> Todd Montgomery Discusses Java 8 Lambdas and Aeron

An interesting 10 minutes discussion on optimizing the way we use Lambdas in Java and why we should care about that.

>> Java 8 WTF: Ambiguous Method Lookup

Ambiguity in the Java Language Spec and a solid and detailed analysis on top. This is a worthwhile article to spend your time on, same as the followup.

>> Asynchronous timeouts with CompletableFuture

A deep dive on how to leverage Java 8 to write better concurrent code.

>> Spring Boot Security Application

A long but useful reference article on building a secured Boot web app.

>> Spring retry – ways to integrate with your project

Retrying a failed operation is one of those things that you may need to do in a mature project. The spring-retry project might help with that.

>> Spring Framework 4.1.4 & 4.0.9 & 3.2.13 released

A cool new Spring release with a lot bug fixes, just before the new year.

And of course, the Spring presentations of the week to keep busy during the following weekend:

2. Technical and Musings

>> Handling Edge Cases

Thinking through the edge cases of your app and handling them well is a sign of maturity and respecting your users even though – yes – it does add quite a bit of complexity to the codebase.

That in no way means you need to do that in your V1 and hold of from launching something useful for fear of unhanded edge cases.

>> Why Intermediation is Important

Most of us are developing for the web in some way, shape or form – and being aware of the potential “points of control” or intermediaries we might be taking for granted makes us better at what we do.

>> Saving a Project and a Company

An in-depth case study of a consulting engagement with a lot of good takeaways for consultants and business owners alike. Lots to learn here.

3. Comics

And some Dilbert to get you started in 2015:

>> Demands for New Year’s Resolutions

>> You think you disagree with me, but you’re mistaken

>> A realistic estimate that will ruin your day

3. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

My Weekly Reviews of 2014

$
0
0

Here’s a handy list of all my 2014 weekly reviews. Learned a lot about curation and picking the most helpful stuff I read this year:

>> Baeldung Weekly Review 1

Interesting articles from week 1 of 2014.

>> Baeldung Weekly Review 2

My takeaways from the 2nd week of 2014.

>> Baeldung Weekly Review 3

Some great Spring, Security and REST articles from the 3rd week of 2014.

>> Baeldung Weekly Review 4

Some great Spring, Security and REST articles from the 4th week of 2014.

>> Baeldung Weekly Review 5

Week 5 review – really good articles on HTTP and REST this week, among other things.

>> Baeldung Weekly Review 6

Another great set of articles out in the 2nd week of February – covering the whole spectrum – Security, Performance testing, patterns and a few other subjects.

>> Baeldung Weekly Review 7

Quite some useful articles this week – and a few must reads, if you’re doing any non-trivial development.

>> Baeldung Weekly Review 8

The 8th weekly review, going wide from the design of a new Hypermedia type to best practices on Unit Testing, and a slew of Spring releases.

>> Baeldung Weekly Review 9

The 9h weekly review starts with the usual Spring releases and great webminars, API architecture and testing resources.

>> Baeldung Weekly Review 10

Great week with lots of articles – from TDD, Software Development attitude, the Circuit Breaker pattern (good one to know) and Programmer Podcasts.

>> Baeldung Weekly Review 11

The week when Java 8 came out – a few good Java 8 articles, some resources on Continuous Delivery and TDD that you should not miss, and an exciting HTTP(S) development.

>> Baeldung Weekly Review 12

The highlights of this week include the second installment of a great TDD video series, a host of Spring releases and webinars, and of course some solid Java 8 resources.

>> Baeldung Weekly Review 13

This week is all about systems in production – starting with a couple of great articles about making sense of log files, real-time analytics and a pragmatic view on reporting.

>> Baeldung Weekly Review 14

This week was packed full of Java 8 articles, a few testing gems and some well researched analyses of production issues.

>> Baeldung Weekly Review 15

The highlights of this week are some great Java 8 usage of lambdas and concurrency improvements, a few helpful Spring posts and a handful of fantastic articles in the “Musings” section.

>> Baeldung Weekly Review 16

This week is all about series and Spring, as well as a back and forth about refactoring as waste and a good start for a set of generic acceptance criteria.

>> Baeldung Weekly Review 17

An solid week for both Java and Spring, as well as very good article (and followup) on building a Hypermedia service from the well known FizzBuzz interview problem.

>> Baeldung Weekly Review 18

This week is definitely about testing – TDD, Unit Testing and the new test support in the upcoming Spring Security 4.

>> Baeldung Weekly Review 19

This week we talk about language and API design nuances, Two-Factor authentication, passwords, and of course testing and TDD.

>> Baeldung Weekly Review 20

Lots of resources this week about TDD, live testing of external services, design and Java 8 – a solid week.

>> Baeldung Weekly Review 21

An interesting week with some cool Spring Security 4 preview articles and the results of the “Capture the Bitcount” bug bounty.

>> Baeldung Weekly Review 22

An interesting week with quite a mixed sample of solid articles being published – Spring, Java, Hibernate and Testing resources.

>> Baeldung Weekly Review 23

This week we discuss the HTTP/1.1 spec update (5 years in the works), some recordings and upcoming Spring webinars and clean testing.

>> Baeldung Weekly Review 24

This has been quite a diverse week – we saw some Spring work on caching and Spring Data and some great testing articles dealing with fixtures and design.

>> Baeldung Weekly Review 25

Spring centric week with some good steps forward for the community – new Spring IO platform, moving to StackOverflow and a few solid webinar recordings.

>> Baeldung Weekly Review 26

Java modularity is getting some attention this week, along with a very pragmatic alternative to the “Big Rewrite” of a software system – definitely a good week.

>> Baeldung Weekly Review 27

Spring Releases galore this week, but also some great Java 8 articles and my favorite podcast recommendation right now.

>> Baeldung Weekly Review 28

This week was packed with value – from 2 very cool Spring Data new features to a few good usecases of Java 8. A very good week.

>> Baeldung Weekly Review 29

A diverse week with a first look at Spring 4.1, the new Servlet 4 draft spec being proposed and some good thoughts on testing.

>> Baeldung Weekly Review 30

Diverse week full of solid articles on Spring, Java 8, testing, BDD and risk management – a lot of interesting articles in here.

>> Baeldung Weekly Review 31

An interesting week – a Java bug got out and got contained, some cool Spring apps are being build and a quick solution to an interview problem that can fit in a tweet.

>> Baeldung Weekly Review 32

Solid week with the new RC2 of Spring 4.1, the Chess TDD series final post and a fantastic writeup on what it means to implement microservices as a team.

>> Baeldung Weekly Review 33

A strong week for the Java/Spring ecosystem – new Java 9 JEPs announced, a REST API being built and some good thoughts on testing.

>> Baeldung Weekly Review 34

This week we’re looking at Spring Boot articles, some solid insights into learning and staying relevant as an engineer and of course – XKCD genius.

>> Baeldung Weekly Review 35

Spring 4.1 is out this week, along with some cool predictions of the next Java Random and some pragmatic musings about testing and goal setting. A good week all in all.

>> Baeldung Weekly Review 36

An interesting Java focused week, as well as a few Spring announcement and a lot of talk around persistence in general and Hibernate in particular.

>> Baeldung Weekly Review 37

The longest weekly review since January – lots of great Java and Spring articles, interesting testing pieces and some good comics.

>> Baeldung Weekly Review 38

Quick and to the point review this week – a solid JUnit tutorial series, a great article on persistence – specifically on long update operations and one my favorite XKCD series.

>> Baeldung Weekly Review 39

Some interesting discussions this week on microservices and solid testing tactics for working with legacy code.

>> Baeldung Weekly Review 40

Some solid articles this week, on code coverage (being a useless metric), interesting JSON Patch Spring experiments and a new installment in the Chess TDD Series.

>> Baeldung Weekly Review 41

Wide array of articles from HTTP/2 moving forward, through using testing as the main driver of your design and to the useful lessons in Microservices.

>> Baeldung Weekly Review 42

A week about Agile, building communities and patch operations in Spring – so not a bad week.

>> Baeldung Weekly Review 43

This week is definitely Spring heavy – lot of solid Spring Boot pieces that show how the framework is maturing. Some interesting JVM articles as well.

>> Baeldung Weekly Review 44

This was quite a week and so we have an interesting roundup. Lots of solid Java and Spring articles as well as some other useful pieces on leadership and affecting positive change.

>> Baeldung Weekly Review 45

This week was all about the next version of Java – the language is definitely not standing still. That and a host of useful Spring replays from SpringOne.

>> Baeldung Weekly Review 46

This week we got some visibility into Java 9, a great microservice deck and tips and tricks for using thread pools.

>> Baeldung Weekly Review 47

Lot happening in Java land – starting with how to understand and tune your severs. Some very interesting uses of Spring Boot and the new Spring Session project.

>> Baeldung Weekly Review 48

A long list of solid pieces this week, starting with some good practices for non-trivial Java projects, to more JDK 9 news and a lot of cool Spring stuff being released.

>> Baeldung Weekly Review 49

One of the more eventful weeks of the year, with some fantastic Spring Boot pieces (and new releases), musings on CQRF and a good read on Flexibility vs Simplicity.

>> Baeldung Weekly Review 50

JDK 9 modularization news, Java 8 streams and Spring Boot – what more can you expect from a good week like this one?

>> Baeldung Weekly Review 51

A quiet week with a few good articles but not a whole lot of activity overall. Also the last review of 2014 – enjoy this one.

Registration with Spring Security – Password Encoding

$
0
0

I usually post about Security on Google+ - you can follow me there:

1. Overview

This article discusses a critical part of the registration process – password encoding – basically not storing the password in plaintext.

There are a few encoding mechanism supported by Spring Security – and for the article we’ll use BCrypt, as it’s usually the best solution available.

Most of the other mechanism, such as the MD5PasswordEncoder and ShaPasswordEncoder use weaker algorithms and are now deprecated.

2. Define the Password Encoder

We’ll start by defining the simple BCryptPasswordEncoder as a bean in our configuration:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

Older implementations – such as SHAPasswordEncoder – would require the client to pass in a salt value when encoding the password.

BCrypt however will internally generate a random salt instead. This is important to understand, because it means that each call will have a different result, and so we need to only encode the password once.

Also be aware that the BCrypt algorithm generates a String of length 60, so we need to make sure that the password will be stored in a column that can accommodate it. A common mistake is to create a column of a different length and then get an Invalid Username or Password error at authentication time.

3. Encode the Password on Registration

We will now use the PasswordEncoder in our UserService to hash the password during the user registration process:

Example 3.1. – The UserService Hashes the Password

@Autowired
private PasswordEncoder passwordEncoder;

@Override
public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
    if (emailExist(accountDto.getEmail())) {
        throw new EmailExistsException(
          "There is an account with that email adress:" + accountDto.getEmail());
    }
    User user = new User();
    user.setFirstName(accountDto.getFirstName());
    user.setLastName(accountDto.getLastName());
    
    user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
    
    user.setEmail(accountDto.getEmail());
    user.setRole(new Role(Integer.valueOf(1), user));
    return repository.save(user);
}

4. Encode the Password on Authentication

Let’s now handle the other half of this process and encode the password when the user authenticates.

First, we need to inject the password encoder bean we defined earlier into our authentication provider:

@Autowired
private UserDetailsService userDetailsService;

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
}

The security configuration is simple:

  • we are injecting our implementation of the users details service
  • we are defining an authentication provider that references our details service
  • we are also enabling the password encoder

And finally, we need to reference this auth provider in our security XML configuration:

<authentication-manager>
    <authentication-provider ref="authProvider" />
</authentication-manager>

5. Conclusion

This quick tutorial continues the Registration series by showing how to properly store the password in the database by leveraging the simple but very powerful BCrypt implementation.

The full implementation of this Registration with Spring Security tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Security on Google+ - you can follow me there:

Baeldung Weekly Review 2

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Java and Spring

>> Using Optional Effectively in Java 8

Optional is one of these things that you may not be using to its full potential.

I’m still getting into the habit of leveraging it and writing Java 8 idiomatic code – so a piece like this, going over practical examples of how to use it in the wild, is quite a good read.

>> Thread Magic Tricks: 5 Things You Never Knew You Can Do with Java Threads

A good reminder of what’s available when working with Java threads, if you’ve not done any low level coding in a while.

>> Stream-Powered Collections Functionality in JDK 8

How to use Java 8 stream syntax for a few useful examples. Not an intro to streams, but a good quick read to see how you can leverage the new functionality in your day to day work.

>> Java 9 and Beyond. Oracle’s Brian Goetz and John Rose Glimpse into the Future

Brian Goetz explains why they’re doing primitive specialization instead of reification for generics in Java 10.

>> Building a Custom Jackson Deserializer

A simple but real world scenario of implementing a Jackson deserializer to better interact with a REST API. Good stuff.

>> Loading view templates from a database with Thymeleaf

An interesting way to mix and match Thymeleaf templates – including loading some of them from the database. An interesting idea to explore.

Next, a few new Spring releases:

Finally, the webinar recordings that are more than worth watching this week(end):

2. Technical and Musings

>> Why you should pay developers to learn

Investing in the team and helping developers grow in their skill has a large impact on what the team can deliver.

In my experience, it takes some times until a team gels and hits that good rhythm of putting out high quality work at a consistent pace. It rarely happens without this kind of ongoing investment.

>> Is This Problem Worth Solving?

It’s hard to understate the impact that a pragmatic mindset has when developing software.

For years, I thought, or kind of assumed that I had it and I was going into all of those scoping sessions with a good eye towards being pragmatic. Nope. Later on I had the good fortune of working with a team leader that was truly focused on simplicity and I realized how much I wasn’t. He would look at a feature from a default of “We’re not going to need that for V1” whereas for me that would only be an afterthought, if that. Learned a lot since then but hitting that good balance, erring on the side of “not needed” and framing that position intelligently is still tough.

So, personal stories aside, go ahead and read this piece – it has some important takeaways.

>> An example of preparatory refactoring

Why preparatory refactoring is a powerful technique to keep a system easy to work with. If a change is hard, you’re probably not going to do it – so it’s a good idea to make it easy first.

>> Theory lags practice

This is such a critical thing to understand, both as a constant learner as well as a teacher.

3. Comics

And the weekly dose of some Dilbert greats:

>> What makes Mark Zuckerberg successful? It’s the shirt.

>> Financial Advisor

>> The “I’m a perfectionist” line

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

I usually post about Dev stuff on Google+ - you can follow me there:

Spring Security – Roles and Privileges

$
0
0

I usually post about Security on Google+ - you can follow me there:

1. Overview

This article continues the Registration with Spring Security series with a look at how to properly implement Roles and Privileges.

2. User Role and Privilege

First, let’s start with our entities. We have three main entities:

  • the User
  • the Role – this represents the high level roles of the user in the system; each role will have a set of low level privileges
  • the Privilege – represents a low level, granular privilege/authority in the system

Here’s the user:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String firstName;
    private String lastName;
    private String email;
    private String password;
    private boolean enabled;
    private boolean tokenExpired;

    @ManyToMany 
    @JoinTable( 
        name = "users_roles", 
        joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) 
    private Collection<Role> roles;
}

As you can see, the user contains the roles, but also a few additional details that are necessary for a proper registration mechanism.

Next – here’s the role:

@Entity
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;
    @ManyToMany(mappedBy = "roles")
    private Collection<User> users;

    @ManyToMany
    @JoinTable(
        name = "roles_privileges", 
        joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "privilege_id", referencedColumnName = "id"))
    private Collection<Privilege> privileges;   
}

And finally the privilege:

@Entity
public class Privilege {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(mappedBy = "privileges")
    private Collection<Role> roles;
}

As you can see, we’re considering both the User <-> Role as well as the Role <-> Privilege relationships many-to-many bidirectional.

3. Setup Privileges and Roles

Next – let’s focus on doing some early setup of the Privileges and Roles in the system.

We’ll tie this to the startup of the application and we’ll use an ApplicationListener on ContextRefreshedEvent to load our initial data on server start:

@Component
public class InitialDataLoader implements ApplicationListener<ContextRefreshedEvent> {

    boolean alreadySetup = false;

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private PrivilegeRepository privilegeRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    @Transactional
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (alreadySetup)
            return;
        Privilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE");
        Privilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE");
        List<Privilege> adminPrivileges = Arrays.asList(readPrivilege, writePrivilege);        
        createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);
        createRoleIfNotFound("ROLE_USER", Arrays.asList(readPrivilege));

        Role adminRole = roleRepository.findByName("ROLE_ADMIN");
        User user = new User();
        user.setFirstName("Test");
        user.setLastName("Test");
        user.setPassword(passwordEncoder.encode("test"));
        user.setEmail("test@test.com");
        user.setRoles(Arrays.asList(adminRole));
        user.setEnabled(true);
        userRepository.save(user);

        alreadySetup = true;
    }

    @Transactional
    private Privilege createPrivilegeIfNotFound(String name) {
        Privilege privilege = privilegeRepository.findByName(name);
        if (privilege == null) {
            privilege = new Privilege(name);
            privilegeRepository.save(privilege);
        }
        return privilege;
    }

    @Transactional
    private Role createRoleIfNotFound(String name, Collection<Privilege> privileges) {
        Role role = roleRepository.findByName(name);
        if (role == null) {
            role = new Role(name);
            role.setPrivileges(privileges);
            roleRepository.save(role);
        }
        return role;
    }
}

So, what’s happening during this simple setup code? Nothing complicated:

  • we’re creating the privileges
  • we’re creating the roles and assigning the privileges to them
  • we’re creating a user and assigning a role to it

Note how we’re using an alreadySetup flag to determine if the setup needs to run or not. This is simply because, depending on how many context you have configured in your application – the ContextRefreshedEvent may be fired multiple times. And we only want setup to be executed once.

4. Custom UserDetailsService

Now – let’s check out the authentication process.

We’re going to see how to retrieve the user within our custom UserDetailsService, and how to map the right set of authorities from the roles and privileges the user has assigned:

@Service("userDetailsService")
@Transactional
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private IUserService service;
    @Autowired
    private MessageSource messages;
    @Autowired
    private RoleRepository roleRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        User user = userRepository.findByEmail(email);
        if (user == null) {
            return new org.springframework.security.core.userdetails.User(
              " ", " ", true, true, true, true, 
              getAuthorities(Arrays.asList(roleRepository.findByName("ROLE_USER"))));
        }

        return new org.springframework.security.core.userdetails.User(
          user.getEmail(), user.getPassword(), user.isEnabled(), true, true, 
          true, getAuthorities(user.getRoles()));
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roles) {
        return getGrantedAuthorities(getPrivileges(roles));
    }

    private List<String> getPrivileges(Collection<Role> roles) {
        List<String> privileges = new ArrayList<String>();
        List<Privilege> collection = new ArrayList<Privilege>();
        for (Role role : roles) {
            collection.addAll(role.getPrivileges());
        }
        for (Privilege item : collection) {
            privileges.add(item.getName());
        }
        return privileges;
    }

    private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (String privilege : privileges) {
            authorities.add(new SimpleGrantedAuthority(privilege));
        }
        return authorities;
    }
}

The interesting thing to follow here is how the Privileges (and Roles) are mapped to GrantedAuthority entities.

This mapping makes the entire security configuration highly flexible and powerful – you can mix and match roles and privileges as granular as necessary, and at the end, they’ll be correctly mapped to authorities and returned back to the framework.

5. User Registration

Finally – let’s take a look at registration for a new user.

We’ve seen how setup goes about creating the User and assigns Roles (and Privileges) to it – let’s now take a look at how this needs to be done during registration of a new user:

@Override
public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
    if (emailExist(accountDto.getEmail())) {
        throw new EmailExistsException
          ("There is an account with that email adress: " + accountDto.getEmail());
    }
    User user = new User();

    user.setFirstName(accountDto.getFirstName());
    user.setLastName(accountDto.getLastName());
    user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
    user.setEmail(accountDto.getEmail());

    user.setRoles(Arrays.asList(roleRepository.findByName("ROLE_USER")));
    return repository.save(user);
}

In this simple implementation, we’re assuming that a standard user is being registered, so the ROLE_USER role is assigned to it.

Of course more complex logic can easily be implemented in the same way – either by having multiple, hardcoded registration methods, or by allowing the client to send the type of user that’s being registered.

6. Conclusion

In this tutorial, we illustrated how to implement Roles and Privileges with JPA, for a Spring Security backed system.

The full implementation of this Registration with Spring Security tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Security on Google+ - you can follow me there:

Baeldung Weekly Review 3

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Spring

>> Spring and Angular JS: A Secure Single Page Application

>> The Login Page: Angular JS and Spring Security Part II

A solid, detailed introduction to securing a single page app with Angular on the front end and Spring Security on the back end. This is going to be an important reference going forward.

>> “Configuring It All Out” or “12-Factor App-Style Configuration with Spring”

Configuration is easy to get wrong. It’s always a balancing act of how much flexibility you want and how much complexity you’re comfortable with. This article gives you the tools you need to do a good job reaching that balance.

Lots of Spring goodness this week (this is why Spring is the first section of the review on this one).

>> Getting Started with Gradle: Creating a Multi-Project Build

Continuing the Gradle series, this article goes into detail on how to structure a multi-module build.

I haven’t jumped on the Gradle bandwagon yet, but if I do, I’ll definitely be coming back to this article for a step-by-step guide on how to do it.

Some very cool presentations:

And the interesting releases of the week:

2. Java

>> Testing with files and directories in JUnit with @Rule

I wasn’t aware of this cool JUnit @Rule for intelligently working with the filesystem – looks helpful.

>> A beginner’s guide to Java Persistence locking

A high level intro to JPA 2.0 / Hibernate locking.

>> Java 8 Streams API as Friendly ForkJoinPool Facade

A few fun exercises using the new Streams API to submit work to a ForkJoinPool.

>> Everything You Need To Know About Default Methods

A good theoretical reference on default methods, aiming to basically cover everything there is to be covered on the subject.

Would benefit from a few more code examples showing how some of the scenarios/examples work. Must have taken a heck of a long time to put together.

3. Technical and Musings

>> The God Login

A thorough analysis of what a good authentication process looks like, what problems it solves and how it can be made so that it doesn’t annoy the crap out of your users.

>> Dissecting an interview question: math is hard

>> Dissecting an interview question: math is hard (part 2)

A fun problem of adding to number together. Yeah.

4. Comics

And the weekly dose of some Dilbert greats:

>> Adding 2 more people to a project

>> It couldn’t be worse

>> Minor website changes

5. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”.

I picked Seanwes before last year – but hey, it’s a new year and there’s a lot more of you reading this now, so you might not have seen it last time. Plus, it takes me seeing something multiple times until it sinks in.

The podcast had a big impact on me last year, and these are the distilled ideas from the podcast, in video form. So – here it is again – Seanwes TV is “jam packed with value“:

>> Seanwes TV

I usually only send the Pick of the Week to email subscribers but I figured – this time I put it here.

I usually post about Dev stuff on Google+ - you can follow me there:

Baeldung Weekly Review 4

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Spring and Java

>> The Resource Server: Angular JS and Spring Security Part III

This 3rd part of a super useful series gets into the nitty-gritty of CORS, a simple Token auth solution and of course Spring Session. Lots to take away from this one, same as the first two.

>> Web App architecture – the Spring MVC – AngularJs stack

Quick and practical intro to the AngularJs + Spring stack.

Yes, there are a slew of articles out there covering this stack, and this is why I haven’t included them in my reviews here, but this one is a simple, solid intro, so here it is.

>> Search In A Box With Docker, Elastic Search, and Selenium

An ATDD driven, pragmatic, elegantly simple article on building a joke search app.

I regularly get this question – What’s the best way for me to start learning X? (Spring, Web development, etc). This isn’t a bad way to start.

>> Fork/Join Framework vs. Parallel Streams vs. ExecutorService: The Ultimate Fork/Join Benchmark

A very interesting analysis/benchmark of the various options to do parallelism in Java – some real numbers to sink your teeth into.

Time to upgrade:

This week comes with a lot of good presentations and webinar recordings:

2. Technical and Musings

>> We Are Gonna Need It

In the hurry to rid ourselves of Waterfall, there’s a real risk of going to far in the other direction. This piece is food for thought on how we might solve that problem.

>> The Internet Is Pseudo-Decentralized

A thought experiment about the topology of the web and how you get to play – a quick and interesting read.

>> I’ll Take a Crack at Defining Tech Debt

A good foray into the all to familiar concept of “technical debt”.

>> Open-Source Service Discovery

Once you have a sufficient number of services you need to orchestrate and deploy into a flexible topology, you have the problem of allowing the services to find each other. Static configuration will no longer cut it.

This article lays out the mature, open-source options available to solve that particular problem.

What’s more, this week we found out that Spring plays quite well with one of these solutions – Netflix’s Eureka: Microservice Registration and Discovery with Spring Cloud and Netflix’s Eureka

>> From Primitive Obsession to Domain Modelling

Sometimes, the domain is the right place to put it.

>> Retiring Python as a Teaching Language

I’ll take pragmatic thinking wherever I can find it. And this reads as both sensible and pragmatic, when trying to answer the question: What’s the best programming language a beginner should start with?

>> Don’t Break the Streak Maybe

An interesting read showing how the well known productivity advice “Don’t break the streak” is now backed into a lot of products. And then blindly doing it just because it’s there.

3. Comics

My favorite Dilberts of the week:

>> Forage during the day. Hide at night.

>> The mandatory impractical requirement

>> The usual project plan arc.

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:


REST Query Language with Spring and JPA Criteria

$
0
0

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

1. Overview

In this first article we’ll explore a simple query language for a REST API. We’ll make good use of Spring for the REST API and JPA 2 Criteria for the persistence aspects.

Why a query language? Because – for any complex enough API – searching/filtering your resources by very simple fields is simply not enough. A query language is more flexible, and allows you to filter down to exactly the resources you need.

2. User Entity

First – let’s put forward the simple entity that we’re going to use for our filter/search API – a basic User:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String firstName;
    private String lastName;
    private String email;

    private int age;
}

3. Filter using CriteriaBuilder

Now – let’s get into the meat of the problem – the query in the persistence layer.

Building a query abstraction is a matter of balance. We need a good amount of flexibility on the one hand, and we need to keep complexity manageable on the other. High level, the functionality is simple – you pass in some constraints and you get back some results.

Let’s see how that works:

@Repository
public class UserDAO implements IUserDAO {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<User> searchUser(List<SearchCriteria> params) {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<User> query = builder.createQuery(User.class);
        Root r = query.from(User.class);

        Predicate predicate = builder.conjunction();

        for (SearchCriteria param : params) {
            if (param.getOperation().equalsIgnoreCase(">")) {
                predicate = builder.and(predicate, 
                  builder.greaterThanOrEqualTo(r.get(param.getKey()), 
                  param.getValue().toString()));
            } else if (param.getOperation().equalsIgnoreCase("<")) {
                predicate = builder.and(predicate, 
                  builder.lessThanOrEqualTo(r.get(param.getKey()), 
                  param.getValue().toString()));
            } else if (param.getOperation().equalsIgnoreCase(":")) {
                if (r.get(param.getKey()).getJavaType() == String.class) {
                    predicate = builder.and(predicate, 
                      builder.like(r.get(param.getKey()), 
                      "%" + param.getValue() + "%"));
                } else {
                    predicate = builder.and(predicate, 
                      builder.equal(r.get(param.getKey()), param.getValue()));
                }
            }
        }
        query.where(predicate);

        List<User> result = entityManager.createQuery(query).getResultList();
        return result;
    }

    @Override
    public void save(User entity) {
        entityManager.persist(entity);
    }
}

As you can see, the searchUser API takes a list of very simple constraints, composes a query based on these constrains, does the search and returns the results.

The constraint class is quite simple as well:

public class SearchCriteria {
    private String key;
    private String operation;
    private Object value;
}

The SearchCriteria implementation holds our Query parameters:

  • key: used to hold field name – for example: firstName, age, … etc.
  • operation: used to hold the operation – for example: Equality, less than, … etc.
  • value: used to hold the field value – for example: john, 25, … etc.

4. Test the Search Queries

Now – let’s test our search mechanism to make sure it holds water.

First – let’s initialize our database for testing by adding two users – as in the following example:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceConfig.class })
@Transactional
@TransactionConfiguration
public class JPACriteriaQueryTest {

    @Autowired
    private IUserDAO userApi;

    private User userJohn;

    private User userTom;

    @Before
    public void init() {
        userJohn = new User();
        userJohn.setFirstName("John");
        userJohn.setLastName("Doe");
        userJohn.setEmail("john@doe.com");
        userJohn.setAge(22);
        userApi.save(userJohn);

        userTom = new User();
        userTom.setFirstName("Tom");
        userTom.setLastName("Doe");
        userTom.setEmail("tom@doe.com");
        userTom.setAge(26);
        userApi.save(userTom);
    }
}

Now, let’s get a User with specific firstName and lastName – as in the following example:

@Test
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
    List<SearchCriteria> params = new ArrayList<SearchCriteria>();
    params.add(new SearchCriteria("firstName", ":", "John"));
    params.add(new SearchCriteria("lastName", ":", "Doe"));

    List<User> results = userApi.searchUser(params);

    assertThat(userJohn, isIn(results));
    assertThat(userTom, not(isIn(results)));
}

Next, let’s get a List of User with the same lastName:

@Test
public void givenLast_whenGettingListOfUsers_thenCorrect() {
    List<SearchCriteria> params = new ArrayList<SearchCriteria>();
    params.add(new SearchCriteria("lastName", ":", "Doe"));

    List<User> results = userApi.searchUser(params);
    assertThat(userJohn, isIn(results));
    assertThat(userTom, isIn(results));
}

Next, let’s get users with age greater than or equal 25:

@Test
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
    List<SearchCriteria> params = new ArrayList<SearchCriteria>();
    params.add(new SearchCriteria("lastName", ":", "Doe"));
    params.add(new SearchCriteria("age", ">", "25"));

    List<User> results = userApi.searchUser(params);

    assertThat(userTom, isIn(results));
    assertThat(userJohn, not(isIn(results)));
}

Next, let’s search for users that don’t actually exist:

@Test
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
    List<SearchCriteria> params = new ArrayList<SearchCriteria>();
    params.add(new SearchCriteria("firstName", ":", "Adam"));
    params.add(new SearchCriteria("lastName", ":", "Fox"));

    List<User> results = userApi.searchUser(params);
    assertThat(userJohn, not(isIn(results)));
    assertThat(userTom, not(isIn(results)));
}

Finally, let’s search for users given only partial firstName:

@Test
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
    List<SearchCriteria> params = new ArrayList<SearchCriteria>();
    params.add(new SearchCriteria("firstName", ":", "jo"));

    List<User> results = userApi.searchUser(params);

    assertThat(userJohn, isIn(results));
    assertThat(userTom, not(isIn(results)));
}

6. The UserController

Finally, let’s now wire in the persistence support for this flexible search to our REST API.

We’re going to be setting up a simple UserController – with a findAll() using the “search” to pass in the entire search/filter expression:

@Controller
public class UserController {

    @Autowired
    private IUserDao api;

    @RequestMapping(method = RequestMethod.GET, value = "/users")
    @ResponseBody
    public List<User> findAll(@RequestParam(value = "search", required = false) String search) {
        List<SearchCriteria> params = new ArrayList<SearchCriteria>();
        if (search != null) {
            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
            Matcher matcher = pattern.matcher(search + ",");
            while (matcher.find()) {
                params.add(new SearchCriteria(matcher.group(1), 
                  matcher.group(2), matcher.group(3)));
            }
        }
        return api.searchUser(params);
    }
}

Note how we’re simply creating our search criteria objects out of the search expression.

We’re not at the point where we can start playing with the API and make sure everything is working correctly:

http://localhost:8080/users?search=lastName:doe,age>25

And here is its response:

[{
    "id":2,
    "firstName":"tom",
    "lastName":"doe",
    "email":"tom@doe.com",
    "age":26
}]

7. Conclusion

This simple yet powerful implementation enables quite a bit of smart filtering on a REST API. Yes – it’s still rough around the edges and can be improved (and will be improved in the next article) – but it’s a solid starting point to implement this kind of filtering functionality on your APIs.

The full implementation of this article can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

REST Query Language with Spring Data JPA Specifications

$
0
0

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

1. Overview

In this tutorial – we will build a Search/Filter REST API using Spring Data JPA and Specifications.

We started looking at a query language in the first article of this series – with a JPA Criteria based solution.

So – why a query language? Because – for any complex enough API – searching/filtering your resources by very simple fields is simply not enough. A query language is more flexible, and allows you to filter down to exactly the resources you need.

2. User Entity

First – let’s start with a simple User entity for our Search API:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String firstName;
    private String lastName;
    private String email;

    private int age;
    
    // standard getters and setters
}

3. Filter using Specifications

Now – let’s get straight into the most interesting part of the problem – querying with custom Spring Data JPA Specifications.

We’ll create a UserSpecification which implements the Specification interface and we’re going to pass in our own constraint to construct the actual query:

public class UserSpecification implements Specification<User> {

    private SearchCriteria criteria;

    @Override
    public Predicate toPredicate
      (Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
        if (criteria.getOperation().equalsIgnoreCase(">")) {
            return builder.greaterThanOrEqualTo(
              root.<String> get(criteria.getKey()), criteria.getValue().toString());
        } 
        else if (criteria.getOperation().equalsIgnoreCase("<")) {
            return builder.lessThanOrEqualTo(
              root.<String> get(criteria.getKey()), criteria.getValue().toString());
        } 
        else if (criteria.getOperation().equalsIgnoreCase(":")) {
            if (root.get(criteria.getKey()).getJavaType() == String.class) {
                return builder.like(
                  root.<String>get(criteria.getKey()), "%" + criteria.getValue() + "%");
            } else {
                return builder.equal(root.get(criteria.getKey()), criteria.getValue());
            }
        }
        return null;
    }
}

As we can see – we create a Specification based on some simple constrains which we represent in the following “SearchCriteria” class:

public class SearchCriteria {
    private String key;
    private String operation;
    private Object value;
}

The SearchCriteria implementation holds a basic representation of a constraint – and it’s based on this constraint that we’re going to be constructing the query:

  • key: the field name – for example: firstName, age, … etc.
  • operation: the operation – for example: equality, less than, … etc.
  • value: the field value – for example: john, 25, … etc.

Of course the implementation is simplistic and can be improved; it is however a solid base for the powerful and flexible operations we need.

4. The UserRepository

Next – let’s take a look at the UserRepository; we’re simply extending the JpaSpecificationExecutor to get the new Specification APIs:

public interface UserRepository 
  extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {}

5. Test the Search Queries

Now – let’s test out the new search API.

First, let’s create a few users to have them ready when the tests runs:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceJPAConfig.class })
@Transactional
@TransactionConfiguration
public class JPASpecificationsTest {

    @Autowired
    private UserRepository repository;

    private User userJohn;
    private User userTom;

    @Before
    public void init() {
        userJohn = new User();
        userJohn.setFirstName("John");
        userJohn.setLastName("Doe");
        userJohn.setEmail("john@doe.com");
        userJohn.setAge(22);
        repository.save(userJohn);

        userTom = new User();
        userTom.setFirstName("Tom");
        userTom.setLastName("Doe");
        userTom.setEmail("tom@doe.com");
        userTom.setAge(26);
        repository.save(userTom);
    }
}

Next, let’s see how to find users with given last name:

@Test
public void givenLast_whenGettingListOfUsers_thenCorrect() {
    UserSpecification spec = 
      new UserSpecification(new SearchCriteria("lastName", ":", "doe"));
    
    List<User> results = repository.findAll(spec);

    assertThat(userJohn, isIn(results));
    assertThat(userTom, isIn(results));
}

Now, let’s see how to find user with given both first and last name:

@Test
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
    UserSpecification spec1 = 
      new UserSpecification(new SearchCriteria("firstName", ":", "john"));
    UserSpecification spec2 = 
      new UserSpecification(new SearchCriteria("lastName", ":", "doe"));
    
    List<User> results = repository.findAll(Specifications.where(spec1).and(spec2));

    assertThat(userJohn, isIn(results));
    assertThat(userTom, not(isIn(results)));
}

Note: We used “where” and “and” to combine Specifications.

Next, let’s see how to find user with given both last name and minimum age:

@Test
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
    UserSpecification spec1 = 
      new UserSpecification(new SearchCriteria("age", ">", "25"));
    UserSpecification spec2 = 
      new UserSpecification(new SearchCriteria("lastName", ":", "doe"));

    List<User> results = 
      repository.findAll(Specifications.where(spec1).and(spec2));

    assertThat(userTom, isIn(results));
    assertThat(userJohn, not(isIn(results)));
}

Now, let’s see how to search for User that doesn’t actually exist:

@Test
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
    UserSpecification spec1 = 
      new UserSpecification(new SearchCriteria("firstName", ":", "Adam"));
    UserSpecification spec2 = 
      new UserSpecification(new SearchCriteria("lastName", ":", "Fox"));

    List<User> results = 
      repository.findAll(Specifications.where(spec1).and(spec2));

    assertThat(userJohn, not(isIn(results)));
    assertThat(userTom, not(isIn(results)));  
}

Finally – let’s see how to find a User given only part of the first name:

@Test
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
    UserSpecification spec = 
      new UserSpecification(new SearchCriteria("firstName", ":", "jo"));
    
    List<User> results = repository.findAll(spec);

    assertThat(userJohn, isIn(results));
    assertThat(userTom, not(isIn(results)));
}

6. Combine Specifications

Next – let’s take a look at combining our custom Specifications to use multiple constraints and filter according to multiple criteria.

We’re going to implement a builder – UserSpecificationsBuilder – to easily and fluently combine Specifications:

public class UserSpecificationsBuilder {
    
    private final List<SearchCriteria> params;

    public UserSpecificationsBuilder() {
        params = new ArrayList<SearchCriteria>();
    }

    public UserSpecificationsBuilder with(String key, String operation, Object value) {
        params.add(new SearchCriteria(key, operation, value));
        return builder;
    }

    public Specification<User> build() {
        if (params.size() == 0) {
            return null;
        }

        List<Specification<User>> specs = new ArrayList<Specification<User>>();
        for (SearchCriteria param : params) {
            specs.add(new UserSpecification(param));
        }

        Specification<User> result = specs.get(0);
        for (int i = 1; i < specs.size(); i++) {
            result = Specifications.where(result).and(specs.get(i));
        }
        return result;
    }
}

7. UserController

Finally – let’s use this new persistence search/filter functionality and set up the REST API – by creating a UserController with a simple search operation:

@Controller
public class UserController {

    @Autowired
    private UserRepository repo;

    @RequestMapping(method = RequestMethod.GET, value = "/users")
    @ResponseBody
    public List<User> search(@RequestParam(value = "search") String search) {
        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
        Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
        Matcher matcher = pattern.matcher(search + ",");
        while (matcher.find()) {
            builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
        }
        
        Specification<User> spec = builder.build();
        return repo.findAll(spec);
    }
}

Here is a test URL example to test out the API:

http://localhost:8080/users?search=lastName:doe,age>25

And the response:

[{
    "id":2,
    "firstName":"tom",
    "lastName":"doe",
    "email":"tom@doe.com",
    "age":26
}]

8. Conclusion

This tutorial covered a simple implementation that can be the base of a powerful REST query language. We’ve made good use of Spring Data Specifications to make sure we keep the API away from the domain and have the option to handle many other types of operations.

The full implementation of this article can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

Baeldung Weekly Review 5

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Spring and Java

>> The API Gateway Pattern: Angular JS and Spring Security Part IV

A proxy/gateway is one of the core questions you need to answer when building your Spring webapp. It helps with quite a few things – CORS being one of them. So – this forth part in the new Spring Security with Angular series unfolding over on Spring Central is a very useful reference to have.

Also – I just removed a topic from my article TODO list – and I didn’t have to write a single word :)

>> Spring 4 and Java 8

A quick guide on how Spring leverages Java 8 to write idiomatic code.

>>  Hibernate locking patterns – How does Optimistic Lock Mode work

An interesting code-focused exploration of Hibernate optimistic locking and more importantly – the potential caveats of using it.

>> Reading Large Lines Slower in JDK 7 and JDK 8

I enjoy reading “Inspired by Actual Events” for these low level deep-dives into the Java language – and this one doesn’t disappoint. Here’s the followup to it.

>> Logging to Redis using Spring Boot and Logback

The ELK stack does wonders for logging – and this is an interesting variation on that. If you’re looking to improve the understanding of your application and your use of logging – this is an solid approach.

But of course the standard ELK stack is also a very good place to start.

>> Timeout support using ExecutorService and Futures

A quick introductory level article on working with a single thread executor and Java 8 streams.

Time to upgrade:

2. Technical and Musings

>> Avoiding the Perfect Design

Pragmatism a clear “exit criteria” are missing in our industry.

You would think it’s a “young gun” mistake, but it’s not. As you’re reading this right now, someone with decades in the industry is crossing his fingers and signing off on The Big Rewrite. Why? Because – maybe this time…

So – maybe don’t do that, and maybe go read this one.

>> Agile Methodologies or Agile Software?

I try to stay away from the Agile writings here on Baeldung. That’s because most of the stuff I read on the subject is just serviceable – sometimes. With a few minor exceptions of course – such as Dan North – but he publishes once every blue moon. This one though – worth reading.

>> Taking the long view

“The long game” is an acquired skill, after you’ve been burned one to many times. And having the discipline to take the necessary steps and track the results long term can be the difference between a successful and a failed project.

>> All the Technology but None of the Love

Good advice.

>> Getting Started with AngularJS

Looks like a solid start with AngularJS – I plan to go through it over the weekend.

3. Comics

And my favorite Dilberts of the week:

>> We’re going to try something called Agile Programming

>> Please don’t hit me with your modem

>> Which answer gets us hired?

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:

REST Query Language with Spring Data JPA and QueryDSL

$
0
0

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

1. Overview

In this tutorial, we’re looking at building a query language for a REST API using Spring Data JPA and Querydsl.

In the first two articles of this series, we built the same search/filtering functionality using JPA Criteria and Spring Data JPA Specifications.

So – why a query language? Because – for any complex enough API – searching/filtering your resources by very simple fields is simply not enough. A query language is more flexible, and allows you to filter down to exactly the resources you need.

2. Querydsl Configuration

First – let’s see how to configure our project to use Querydsl.

We need to add the following dependencies to pom.xml:

<dependency> 
    <groupId>com.mysema.querydsl</groupId> 
    <artifactId>querydsl-core</artifactId> 
    <version>3.6.0</version>
</dependency> 
<dependency> 
    <groupId>com.mysema.querydsl</groupId> 
    <artifactId>querydsl-apt</artifactId> 
    <version>3.6.0</version>
    </dependency>
<dependency> 
    <groupId>com.mysema.querydsl</groupId> 
    <artifactId>querydsl-jpa</artifactId> 
    <version>3.6.0</version> 
</dependency>

We also need to configure the APT – Annotation processing tool – plugin as follows:

<plugin>
    <groupId>com.mysema.maven</groupId>
    <artifactId>apt-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
        <execution>
            <goals>
                <goal>process</goal>
            </goals>
            <configuration>
                <outputDirectory>target/generated-sources/java</outputDirectory>
                <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
            </configuration>
        </execution>
    </executions>
</plugin>

3. The User Entity

Next – let’s take a look at the “User” entity which we are going to use in our Search API:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String firstName;
    private String lastName;
    private String email;

    private int age;
}

4. Custom Predicate with PathBuilder

Now – let’s create a custom Predicate based on some arbitrary constraints.

We’re using PathBuilder here instead of the automatically generated Q-types because we need to create paths dynamically for more abstract usage:

public class UserPredicate {

    private SearchCriteria criteria;

    public BooleanExpression getPredicate() {
        PathBuilder<User> entityPath = new PathBuilder<User>(User.class, "user");

        if (isNumeric(criteria.getValue().toString())) {
            NumberPath<Integer> path = entityPath.getNumber(criteria.getKey(), Integer.class);
            int value = Integer.parseInt(criteria.getValue().toString());
            if (criteria.getOperation().equalsIgnoreCase(":")) {
                return path.eq(value);
            } 
            else if (criteria.getOperation().equalsIgnoreCase(">")) {
                return path.goe(value);
            } 
            else if (criteria.getOperation().equalsIgnoreCase("<")) {
                return path.loe(value);
            }
        } 
        else {
            StringPath path = entityPath.getString(criteria.getKey());
            if (criteria.getOperation().equalsIgnoreCase(":")) {
                return path.containsIgnoreCase(criteria.getValue().toString());
            }
        }
        return null;
    }
}

Note how the implementation of the predicate is generically dealing with multiple types of operations. This is because the query language is by definition an open language where you can potentially filter by any field, using any supported operation.

To represent that kind of open filtering criteria, we’re using a simple but quite flexible implementation – SearchCriteria:

public class SearchCriteria {
    private String key;
    private String operation;
    private Object value;
}

The SearchCriteria holds the details we need to represent a constraint:

  • key: the field name – for example: firstName, age, … etc
  • operation: the operation – for example: Equality, less than, … etc
  • value: the field value – for example: john, 25, … etc

5. UserRepository

Now – let’s take a look at our UserRepository.

We need our UserRepository to extend QueryDslPredicateExecutor so that we can use Predicates later to filter search results:

public interface UserRepository extends JpaRepository<User, Long>, 
                                        QueryDslPredicateExecutor<User> {}

6. Combine Predicates

Next– let’s take a look at combining Predicates to use multiple constraints in results filtering.

In the following example – we work with a builder – UserPredicatesBuilder  – to combine Predicates:

public class UserPredicatesBuilder {
    private List<SearchCriteria> params;

    public UserPredicatesBuilder() {
        params = new ArrayList<SearchCriteria>();
    }

    public UserPredicatesBuilder with(String key, String operation, Object value) {
        params.add(new SearchCriteria(key, operation, value));
        return this;
    }

    public BooleanExpression build() {
        if (params.size() == 0) {
            return null;
        }

        List<BooleanExpression> predicates = new ArrayList<BooleanExpression>();
        UserPredicate predicate;
        for (SearchCriteria param : params) {
            predicate = new UserPredicate(param);
            BooleanExpression exp = predicate.getPredicate();
            if (exp != null) {
                predicates.add(exp);
            }
        }

        BooleanExpression result = predicates.get(0);
        for (int i = 1; i < predicates.size(); i++) {
            result = result.and(predicates.get(i));
        }
        return result;
    }
}

7. Test the Search Queries

Next – let’s test our Search API.

We’ll start by initializing the database with a few users – to have these ready and available for testing:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceConfig.class })
@Transactional
@TransactionConfiguration
public class JPAQuerydslTest {

    @Autowired
    private UserRepository repo;

    private User userJohn;
    private User userTom;

    @Before
    public void init() {
        userJohn = new User();
        userJohn.setFirstName("John");
        userJohn.setLastName("Doe");
        userJohn.setEmail("john@doe.com");
        userJohn.setAge(22);
        repo.save(userJohn);

        userTom = new User();
        userTom.setFirstName("Tom");
        userTom.setLastName("Doe");
        userTom.setEmail("tom@doe.com");
        userTom.setAge(26);
        repo.save(userTom);
    }
}

Next, let’s see how to find users with given last name:

@Test
public void givenLast_whenGettingListOfUsers_thenCorrect() {
    UserPredicatesBuilder builder = new UserPredicatesBuilder().with("lastName", ":", "Doe");

    Iterable<User> results = repo.findAll(builder.build());
    assertThat(results, containsInAnyOrder(userJohn, userTom));
}

Now, let’s see how to find user with given both first and last name:

@Test
public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
    UserPredicatesBuilder builder = new UserPredicatesBuilder()
      .with("firstName", ":", "John").with("lastName", ":", "Doe");

    Iterable<User> results = repo.findAll(builder.build());

    assertThat(results, contains(userJohn));
    assertThat(results, not(contains(userTom)));
}

Next, let’s see how to find user with given both last name and minimum age

@Test
public void givenLastAndAge_whenGettingListOfUsers_thenCorrect() {
    UserPredicatesBuilder builder = new UserPredicatesBuilder()
      .with("lastName", ":", "Doe").with("age", ">", "25");

    Iterable<User> results = repo.findAll(builder.build());

    assertThat(results, contains(userTom));
    assertThat(results, not(contains(userJohn)));
}

Now, let’s see how to search for User that doesn’t actually exist:

@Test
public void givenWrongFirstAndLast_whenGettingListOfUsers_thenCorrect() {
    UserPredicatesBuilder builder = new UserPredicatesBuilder()
      .with("firstName", ":", "Adam").with("lastName", ":", "Fox");

    Iterable<User> results = repo.findAll(builder.build());
    assertThat(results, emptyIterable());
}

Finally – let’s see how to find a User given only part of the first name – as in the following example:

@Test
public void givenPartialFirst_whenGettingListOfUsers_thenCorrect() {
    UserPredicatesBuilder builder = new UserPredicatesBuilder().with("firstName", ":", "jo");

    Iterable<User> results = repo.findAll(builder.build());

    assertThat(results, contains(userJohn));
    assertThat(results, not(contains(userTom)));
}

8. UserController

Finally, let’s put everything together and build the REST API.

We’re defining a UserController that defines a simple method findAll() with a “search“ parameter to pass in the query string:

@Controller
public class UserController {

    @Autowired
    private UserRepository repo;

    @RequestMapping(method = RequestMethod.GET, value = "/users")
    @ResponseBody
    public Iterable<User> search(@RequestParam(value = "search") String search) {
        UserPredicatesBuilder builder = new UserPredicatesBuilder();

        if (search != null) {
            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
            Matcher matcher = pattern.matcher(search + ",");
            while (matcher.find()) {
                builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
            }
        }
        BooleanExpression exp = builder.build();
        return repo.findAll(exp);
    }
}

Here is a quick test URL example:

http://localhost:8080/users?search=lastName:doe,age>25

And the response:

[{
    "id":2,
    "firstName":"tom",
    "lastName":"doe",
    "email":"tom@doe.com",
    "age":26
}]

9. Conclusion

This third article covered the first steps of building a query language for a REST API, making good use of the Querydsl library.

The implementation is of course early on, but it can easily be evolved to support additional operations.

The full implementation of this article can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

Spring JDBC

$
0
0

I usually post about Persistence on Google+ - you can follow me there:

1. Overview

In this article we’ll go through practical usecases of the Spring JDBC module.

All the classes in Spring JDBC are divided into four separate packages:

  • core – the core functionality of JDBC. Some of the important classes under this package include JdbcTemplate, SimpleJdbcInsert, SimpleJdbcCall and NamedParameterJdbcTemplate.
  • datasource – utility classes to access datasource. It also has various datasource implementations that could be used for testing JDBC code outside the Java EE container.
  • object – DB access in an object oriented manner. It allows executing queries and returning the results as a business object. It maps the query results between the columns and properties of business objects.
  • support – support classes for classes under core and object packages. E.g. provides the SQLException translation functionality.

2. Configuration

Let’s start with some simple configuration of the datasource (we’ll use MySQL database for this example):

@Configuration
@ComponentScan("org.baeldung.jdbc")
public class SpringJdbcConfig {
    @Bean
    public DataSource mysqlDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/springjdbc");
        dataSource.setUsername("guest_user");
        dataSource.setPassword("guest_password");

        return dataSource;
    }
}

Alternatively, you can also make good use of an embedded database for development or testing – here is a quick configuration that creates an instance of HSQL embedded database and pre-populates it with a simple SQL scripts:

@Bean
public DataSource dataSource() {
    return new EmbeddedDatabaseBuilder()
        .setType(EmbeddedDatabaseType.HSQL)
        .addScript("classpath:jdbc/schema.sql")
        .addScript("classpath:jdbc/test-data.sql").build();
}

Finally – the same can of course be done using XML configuring for the datasource:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
  destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/springjdbc"/>
    <property name="username" value="guest_user"/>
    <property name="password" value="guest_password"/>
</bean>

3. The JdbcTemplate and running queries

3.1. Basic Queries

The JDBC template is the main API through which we’ll access most of the functionality that we’re interested in:

  • creation and closing of connections
  • executing statements and stored procedure calls
  • iterating over the ResultSet and returning results

Let’s start with a simple example to see what the JdbcTemplate can do:

int result = jdbcTemplate.queryForObject(
    "SELECT COUNT(*) FROM EMPLOYEE", Integer.class);

And here’s a simple INSERT:

public int addEmplyee(int id) {
    return jdbcTemplate.update(
        "INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", 5, "Bill", "Gates", "USA");
}

Notice the standard syntax of providing parameters – using the `?` character. Next – let’s look at an alternative to this syntax.

3.2. Queries with Named Parameters

To get support for named parameters, we’ll use the other JDBC template provided by the framework – the NamedParameterJdbcTemplate.

This wraps the JbdcTemplate and provides an alternative to the traditional syntax using “?” to specify parameters. Under the hood, it substitutes the named parameters to JDBC “?” placeholder and delegates to the wrapped JDCTemplate to execute the queries:

SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("id", 1);
return namedParameterJdbcTemplate.queryForObject(
    "SELECT FIRST_NAME FROM EMPLOYEE WHERE ID = :id", namedParameters, String.class);

Notice how we are using the MapSqlParameterSource to provide the values for the named parameters.

Next – a quick example that uses properties from a bean to determine the named parameters:

Employee employee = new Employee();
employee.setFirstName("James");

String SELECT_BY_ID = "SELECT COUNT(*) FROM EMPLOYEE WHERE FIRST_NAME = :firstName";

SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(employee);
return namedParameterJdbcTemplate.queryForObject(SELECT_BY_ID, namedParameters, Integer.class);

Note how we’re now making use of the BeanPropertySqlParameterSource implementations instead of specifying the named parameters manually like before.

3.3. Mapping Query Results to Java Object

Another very useful feature is the ability to map query results to java objects – by implementing RowMapper interface.

For example – for every row returned by the query, Spring uses the row mapper to populate the java bean:

public class EmployeeRowMapper implements RowMapper<Employee> {
    @Override
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
        Employee employee = new Employee();

        employee.setId(rs.getInt("ID"));
        employee.setFirstName(rs.getString("FIRST_NAME"));
        employee.setLastName(rs.getString("LAST_NAME"));
        employee.setAddress(rs.getString("ADDRESS"));

        return employee;
    }
}

We can now pass the row mapper to the query API and get fully populated Java objects back:

String query = "SELECT * FROM EMPLOYEE WHERE ID = ?";
List<Employee> employees = jdbcTemplate.queryForObject(
    query, new Object[] { id }, new EmployeeRowMapper());

4. Exception Translation

Spring comes with its own data exception hierarchy out of the box – with DataAccessException as the root exception – and it translates all underlying raw exceptions to it.

And so you keep your sanity by not having to handle low level persistence exceptions and benefit from the fact that Spring wraps the low level exceptions in DataAccessException or one of it’s sub-classes.

This keeps the exception handling mechanism independent of the underlying database you’re using.

Besides the default SQLErrorCodeSQLExceptionTranslator you can also provide your own implementation of SQLExceptionTranslator.

Here’s a quick example of a custom implementation, customizing the error message when there is integrity constraint violation:

public class CustomSQLErrorCodeTranslator extends SQLErrorCodeSQLExceptionTranslator {
    @Override
    protected DataAccessException customTranslate
      (String task, String sql, SQLException sqlException) {
        if (sqlException.getErrorCode() == -104) {
            return new DuplicateKeyException(
                "Custom Exception translator - Integrity constraint violation.", sqlException);
        }
        return null;
    }
}

To use this custom exception translator, we need to pass it to the JdbcTemplate by calling setExceptionTranslator() method:

CustomSQLErrorCodeTranslator customSQLErrorCodeTranslator = new CustomSQLErrorCodeTranslator();
jdbcTemplate.setExceptionTranslator(customSQLErrorCodeTranslator);

5. JDBC operations using SimpleJdbc classes

SimpleJdbc classes provide easy way to configure and execute SQL statements. These classes use database metadata to build basic queries. SimpleJdbcInsert and SimpleJdbcCall classes provide easier way to execute insert and stored procedure calls.

5.1. SimpleJdbcInsert

Next – let’s take a look at executing simple insert statements with minimal configuration; the INSERT statement is generated based on the configuration of SimpleJdbcInsert.

All you need to provide is the Table name, Column names and values. Let’s first create the SimpleJdbcInsert:

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("EMPLOYEE");

Now, let’s provide the Column names and values, and execute the operation:

public int addEmplyee(Employee emp) {
    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put("ID", emp.getId());
    parameters.put("FIRST_NAME", emp.getFirstName());
    parameters.put("LAST_NAME", emp.getLastName());
    parameters.put("ADDRESS", emp.getAddress());

    return simpleJdbcInsert.execute(parameters);
}

To allow the database to generate the primary key, we can make use of the executeAndReturnKey() API; we’ll also need to configure the actual column that is auto-generated:

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
                                        .withTableName("EMPLOYEE")
                                        .usingGeneratedKeyColumns("ID");

Number id = simpleJdbcInsert.executeAndReturnKey(parameters);
System.out.println("Generated id - " + id.longValue());

Finally – we can also pass in this data by using the BeanPropertySqlParameterSource and MapSqlParameterSource.

5.2. Stored Procedures with SimpleJdbcCall

Let’s now take a look at executing stored procedures – we’ll make use of the SimpleJdbcCall abstraction:

SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource)
		                     .withProcedureName("READ_EMPLOYEE");

public Employee getEmployeeUsingSimpleJdbcCall(int id) {
    SqlParameterSource in = new MapSqlParameterSource().addValue("in_id", id);
    Map<String, Object> out = simpleJdbcCall.execute(in);

    Employee emp = new Employee();
    emp.setFirstName((String) out.get("FIRST_NAME"));
    emp.setLastName((String) out.get("LAST_NAME"));

    return emp;
}

6. Batch operations

Another simple usecase – batching multiple operations together.

6.1. Basic batch operations using JdbcTemplate

Using JdbcTemplate, batch operations can be executed via the batchUpdate() API.

The interesting part here is the concise but highly useful BatchPreparedStatementSetter implementation:

public int[] batchUpdateUsingJdbcTemplate(List<Employee> employees) {
    return jdbcTemplate.batchUpdate("INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)",
        new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setInt(1, employees.get(i).getId());
                ps.setString(2, employees.get(i).getFirstName());
                ps.setString(3, employees.get(i).getLastName());
                ps.setString(4, employees.get(i).getAddress();
            }
            @Override
            public int getBatchSize() {
                return 50;
            }
        });
}

6.2. Batch operations using NamedParameterJdbcTemplate

You also have the option of batching operations with the NamedParameterJdbcTemplatebatchUpdate() API.

This API is simpler than the previous one – no need to implement any extra interfaces to set the parameters, as it has an internal prepared statement setter to set the parameter values.

Instead, the parameter values can be passed to the batchUpdate() method as an array of SqlParameterSource.

SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(employees.toArray());
int[] updateCounts = namedParameterJdbcTemplate.batchUpdate(
    "INSERT INTO EMPLOYEE VALUES (:id, :firstName, :lastName, :address)", batch);
return updateCounts;

7. Conclusion

In this quick tutorial we looked at the JDBC abstraction in the Spring Framework, covering the various built capabilities provided by Spring JDBC with practical examples.

I usually post about Persistence on Google+ - you can follow me there:

Spring JPA – Multiple Databases

$
0
0

I usually post about Persistence on Google+ - you can follow me there:

1. Overview

In this tutorial we’ll implement a simple Spring configuration for a Spring Data JPA system with multiple databases.

2. The Entities

First – let’s create two simple entities – each living in a separate database.

Here is the first entity “User“:

package org.baeldung.persistence.multiple.model.user;

@Entity
@Table(schema = "spring_jpa_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;

    @Column(unique = true, nullable = false)
    private String email;

    private int age;
}

And the second entity – “Product“:

package org.baeldung.persistence.multiple.model.product;

@Entity
@Table(schema = "spring_jpa_product")
public class Product {

    @Id
    private int id;

    private String name;

    private double price;
}

As you can see, the two entities are also placed in independent packages – this will be important as we move into the configuration.

3. The JPA Repositories

Next – let’s take a look at our two JPA repositories – UserRepository:

package org.baeldung.persistence.multiple.dao.user;

public interface UserRepository extends JpaRepository<User, Integer> { }

And ProductRepository:

package org.baeldung.persistence.multiple.dao.product;

public interface ProductRepository extends JpaRepository<Product, Integer> { }

Note, again how we created these two repositories in different packages.

4. Configure JPA with Java

Next – let’s get to the actual Spring configuration. We’ll start by setting up 2 configuration classes – one for the User and the other for the Product.

In each one of this configuration classes, we’ll need to define the following:

  • User DataSource
  • User EntityManagerFactory (userEntityManager)
  • User TransactionManager (userTransactionManager)

Let’s start by looking the the User configuration:

@Configuration
@PropertySource({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories(
    basePackages = "org.baeldung.persistence.multiple.dao.user", 
    entityManagerFactoryRef = "userEntityManager", 
    transactionManagerRef = "userTransactionManager"
)
public class UserConfig {
    @Autowired
    private Environment env;
    
    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean userEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(userDataSource());
        em.setPackagesToScan(new String[] { "org.baeldung.persistence.multiple.model.user" });

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
        em.setJpaPropertyMap(properties);

        return em;
    }

    @Primary
    @Bean
    public DataSource userDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("user.jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.user"));
        dataSource.setPassword(env.getProperty("jdbc.pass"));

        return dataSource;
    }

    @Primary
    @Bean
    public PlatformTransactionManager userTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(userEntityManager().getObject());
        return transactionManager;
    }
}

Notice how we’re using the userTransactionManager as our Primary TransactionManager – by annotating the bean definition with @Primary. That’s helpful whenever we’re going to implicitly or explicitly inject the transaction manager without specifying which one by name.

Next, let’s discuss ProductConfig - where we define similar beans:

@Configuration
@PropertySource({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories(
    basePackages = "org.baeldung.persistence.multiple.dao.product", 
    entityManagerFactoryRef = "productEntityManager", 
    transactionManagerRef = "productTransactionManager"
)
public class ProductConfig {
    @Autowired
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean productEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(productDataSource());
        em.setPackagesToScan(new String[] { "org.baeldung.persistence.multiple.model.product" });

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
        em.setJpaPropertyMap(properties);

        return em;
    }

    @Bean
    public DataSource productDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("product.jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.user"));
        dataSource.setPassword(env.getProperty("jdbc.pass"));

        return dataSource;
    }

    @Bean
    public PlatformTransactionManager productTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(productEntityManager().getObject());
        return transactionManager;
    }
}

5. Simple Test

Finally – let’s test our configurations.

We will try a simple test by creating an instance of each entity and make sure it is created – as in the following example:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { UserConfig.class, ProductConfig.class })
@TransactionConfiguration
public class JPAMultipleDBTest {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ProductRepository productRepository;

    @Test
    @Transactional("userTransactionManager")
    public void whenCreatingUser_thenCreated() {
        User user = new User();
        user.setName("John");
        user.setEmail("john@test.com");
        user.setAge(20);
        user = userRepository.save(user);

        assertNotNull(userRepository.findOne(user.getId()));
    }

    @Test
    @Transactional("userTransactionManager")
    public void whenCreatingUsersWithSameEmail_thenRollback() {
        User user1 = new User();
        user1.setName("John");
        user1.setEmail("john@test.com");
        user1.setAge(20);
        user1 = userRepository.save(user1);
        assertNotNull(userRepository.findOne(user1.getId()));

        User user2 = new User();
        user2.setName("Tom");
        user2.setEmail("john@test.com");
        user2.setAge(10);
        try {
            user2 = userRepository.save(user2);
        } catch (DataIntegrityViolationException e) {
        }

        assertNull(userRepository.findOne(user2.getId()));
    }

    @Test
    @Transactional("productTransactionManager")
    public void whenCreatingProduct_thenCreated() {
        Product product = new Product();
        product.setName("Book");
        product.setId(2);
        product.setPrice(20);
        product = productRepository.save(product);

        assertNotNull(productRepository.findOne(product.getId()));
    }
}

6. Conclusion

This article was a practical overview of how to configure your Spring Data JPA project to use multiple databases.

The full implementation of this article can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Persistence on Google+ - you can follow me there:

Baeldung Weekly Review 6

$
0
0

I usually post about Dev stuff on Google+ - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Spring and Java

>> How to fix optimistic locking race conditions with pessimistic locking

Combining pessimistic and optimistic locking with Hibernate to keep the integrity of your data.

>> Top 5 Use-Cases For Nested Types

With the advent of lambdas, a deep dive, back-to-roots piece on Java nested classes is quite helpful, at least for a solid grasp of the basics.

>> Inconsistent operation widen rules in Java

Another back-to-basics with Java – a nice reminder on working with numerical primitives.

>> Programmatically Determining Java Class’s JDK Compilation Version

Another cool, low level Java article – this time about determining the version of the JDK that compiled a class. I didn’t even know it was possible.

>> Storing months of historical metrics from Hystrix in Graphite

Very cool solution for monitoring your app.

I’ve been using various permutations for monitoring – CollectD and Graphite (and more recently Kibana) being the most common – but this looks quite slick.

>> SSO with OAuth2: Angular JS and Spring Security Part V

Getting into more advanced topics with the 5th part of the AngularJS and Spring Security series – with a deep dive into OAuth and SSO.

>> Why 12 Factor Application Patterns, Microservices and CloudFoundry Matter

Complicated, manual and error prone deployment processes – that brings me back; the industry has come a long way since the early days.

And some good talks to have fun with during the weekend:

Time to upgrade:

2. Technical and Musings

>> Cutting Down on Code Telepathy

“Out of Band” required knowledge to interact with an API is usually not good. A REST architecture addresses the problem via the HATEOAS constraint and Media Types. However this is not a REST-only issue, but a question to be asked when designing any API:

Does the caller require any out of band knowledge to consume the API?

If so, this is a cost; depending on the situation, it may be a cost you want to take on, but it should always be an intentional decision.

>> The Army of the New Independents

The job / employment landscape is changing, and fast. So, if you are already independent or thinking about it, this is a good one to read to give you some context.

>> Programmer IS A Career Path, Thank You

The Musings section is good advice this week – have a read.

>> Let’s Talk About Your Backups

Wake up call?

3. Comics

And my favorite Dilberts of the week:

>> The Problem with Randomness (you can never be sure)

>> Buzzwords

>> Empty Jargon

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

I usually post about Dev stuff on Google+ - you can follow me there:


Baeldung Weekly Review 7

$
0
0

I usually post about Dev stuff on Twitter - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually interesting.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Spring and Java

>> Better application events in Spring Framework 4.2

Events in Spring are getting a much needed upgrade – this is going to make events a lot more powerful and useful.

>> Introducing JHipster

A quick and solid intro go JHipster, a stack that I’ve been following for a while.

>> Hibernate locking patterns – How does OPTIMISTIC_FORCE_INCREMENT Lock Mode work

Yet another code driven, in-depth exploration of locking strategies in Hibernate – this one about the the OPTIMISTIC_FORCE_INCREMENT mode.

>> Java Doesn’t Suck – Rockin’ the JVM

An interesting rundown of how the Spring ecosystem makes java development easy and lightweight.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical and Musings

>> Spotting Bad Actors: What Your Logs Can Tell You About Protecting Your Business

Very cool usecases for using Elasticsearch to determine bad traffic to your site. Invaluable information to have when mitigating an attack or just sanitizing your network input.

>> Writing Just Enough Documentation

Doing Agile and writing documentation are certainly not mutually exclusive – but it does take some experience to navigate the situation. This article will get you one stop closer to doing that well.

>> Time Zone Use Cases

Sound advice on how to deal with the necessary evil that is timezones.

>> This Uncanny Valley of Voice Recognition

Voice recognition is great when it works and infuriating the rest of the time. Have a read and explore the why, or it least if you want to actually laugh out loud.

>> Aggregation of Indignities

Sometimes, this is why people quit.

3. Comics

And my favorite Dilberts of the week:

>> Dating as A/B Testing

>> Something called Blame

>> I like dancing; I’m out

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

PS: I’m very happy that I’m going to be speaking at Spring.io in Barcelona at the end of April. It’s a great event and lineup, so I hope to do the conference justice.

 

I usually post about Dev stuff on Twitter - you can follow me there:

Prevent Brute Force Authentication Attempts with Spring Security

$
0
0

I usually post about Security on Twitter - you can follow me there:

1. Overview

In this quick tutorial, we’ll implement a basic solution for preventing brute force authentication attempts using Spring Security.

Simply put – we’ll keep a record of the number of failed attempts originating from a single IP address. If that particular IP goes over a set number of requests – it will be blocked for 24 hours.

2. An AuthenticationFailureEventListener

Let’s start by defining a AuthenticationFailureEventListener – to listen to AuthenticationFailureBadCredentialsEvent events and notify us of of an authentication failure:

@Component
public class AuthenticationFailureListener 
  implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {

    @Autowired
    private LoginAttemptService loginAttemptService;

    public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent e) {
        WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails();
        loginAttemptService.loginFailed(auth.getRemoteAddress());
    }
}

Note how, when authentication fails, we inform the LoginAttemptService of the IP address from where the unsuccessful attempt originated.

3. An AuthenticationSuccessEventListener

Let’s also define a AuthenticationSuccessEventListener - which listens for AuthenticationSuccessEvent events and notifies us of a successful authentication:

@Component
public class AuthenticationSuccessEventListener 
  implements ApplicationListener<AuthenticationSuccessEvent> {

    @Autowired
    private LoginAttemptService loginAttemptService;

    public void onApplicationEvent(AuthenticationSuccessEvent e) {
        WebAuthenticationDetails auth = (WebAuthenticationDetails) e.getAuthentication().getDetails();
        loginAttemptService.loginSucceeded(auth.getRemoteAddress());
    }
}

Note how – similar to the failure listener, we’re notifying the LoginAttemptService of the IP address from which the authentication request originated.

4. The LoginAttemptService

Now – let’s discuss our LoginAttemptService implementation; simply put – we keep the number of wrong attempts per IP address for 24 hours:

@Service
public class LoginAttemptService {

    private final int MAX_ATTEMPT = 10;
    private LoadingCache<String, Integer> attemptsCache;

    public LoginAttemptService() {
        super();
        attemptsCache = CacheBuilder.newBuilder().
          expireAfterWrite(1, TimeUnit.DAYS).build(new CacheLoader<String, Integer>() {
            public Integer load(String key) {
                return 0;
            }
        });
    }

    public void loginSucceeded(String key) {
        attemptsCache.invalidate(key);
    }

    public void loginFailed(String key) {
        int attempts = 0;
        try {
            attempts = attemptsCache.get(key);
        } catch (ExecutionException e) {
            attempts = 0;
        }
        attempts++;
        attemptsCache.put(key, attempts);
    }

    public boolean isBlocked(String key) {
        try {
            return attemptsCache.get(key) >= MAX_ATTEMPT;
        } catch (ExecutionException e) {
            return false;
        }
    }
}

Notice how an unsuccessful authentication attempt increases the number of attempts for that IP, and the successful authentication resets that counter.

From this point, it’s simply a matter of checking the counter when we authenticate.

5. Modify the UserDetailsService

Now, let’s ad the extra check in our custom UserDetailsService implementation; when we load the UserDetails, we first check if this IP address is blocked:

@Service("userDetailsService")
@Transactional
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private LoginAttemptService loginAttemptService;

    @Autowired
    private HttpServletRequest request;


    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        String ip = request.getRemoteAddr();
        if (loginAttemptService.isBlocked(ip)) {
            throw new RuntimeException("blocked");
        }

        try {
            User user = userRepository.findByEmail(email);
            if (user == null) {
                return new org.springframework.security.core.userdetails.User(
                  " ", " ", true, true, true, true, 
                  getAuthorities(Arrays.asList(roleRepository.findByName("ROLE_USER"))));
            }

            return new org.springframework.security.core.userdetails.User(
              user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, 
              getAuthorities(user.getRoles()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

The interesting part is is how we are autowiring in the HTTP request; we do this because we need to access the IP address and we cannot modify the signature of the loadUserByUsername method. In order to be able to do this, we need to add some additional logic into our web.xml.

6. The web.xml

We need to add RequestContextListener to our web.xml to be able to access the request from the UserDetailsService:

<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>

7. Modify login.jsp

Finally – let’s take care of the front-end and modify our login.jsp.

We’re handling the situation when the user actually does get blocked for 24 hours – and we’re informing the user that his IP is blocked because he exceeded the maximum allowed wrong authentication attempts:

<c:if test="${param.error != null}">
    <c:choose>
        <c:when test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'User is disabled'}">
	    <div class="alert alert-error">
                <spring:message code="auth.message.disabled"></spring:message>
	    </div>
	</c:when>
	<c:when test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'User account has expired'}">
	    <div class="alert alert-error">
	        <spring:message code="auth.message.expired"></spring:message>
	    </div>
	</c:when>
	<c:when test="${SPRING_SECURITY_LAST_EXCEPTION.message == 'blocked'}">
            <div class="alert alert-error">
                <spring:message code="auth.message.blocked"></spring:message>
            </div>
        </c:when>
	<c:otherwise>
	    <div class="alert alert-error">
	        <spring:message code="message.badCredentials"></spring:message>
            </div>
        </c:otherwise>
    </c:choose>
</c:if>

8. Conclusion

It’s important to understand that this is a good first step in dealing with brute-force password attempts, but also that there’s a room for improvement. A production grade brute-force prevention strategy may involve more than elements that an IP block.

The full implementation of this tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Security on Twitter - you can follow me there:


Spring Security – Reset Your Password

$
0
0

I usually post about Security on Twitter - you can follow me there:

1. Overview

In this tutorial – we’re continuing the ongoing Registration with Spring Security series with a look at the basic “I forgot my password” feature – so that the user can safely reset their own password when they need to.

2. The Password Reset Token

Let’s start by creating a PasswordResetToken entity to use it for resetting the users password:

@Entity
public class PasswordResetToken {

    private static final int EXPIRATION = 60 * 24;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String token;

    @OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable = false, name = "user_id")
    private User user;

    private Date expiryDate;
}

When a password reset is triggered – a token will be created and a special link containing this token will be emailed to the user.

The token and the link will only be valid for a set period of time (24 hours in this example).

3. forgotPassword.html

The first page in the process is the “I forgot my password” page – where the user is prompted for their email address in order for the actual reset process to start.

So – let’s craft a simple forgotPassword.html asking the user for an email address:

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="sec"	uri="http://www.springframework.org/security/tags"%>
<%@ page session="false"%>
<html>
<head>
    <link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
    <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
    <title><spring:message code="message.resetPassword"></spring:message></title>
</head>
<body>
<div class="container">
<div class="span12">
<h1>
    <spring:message code="message.resetPassword"></spring:message>
</h1>
<div>
<br>

<tr>
    <td><label><spring:message code="label.user.email"></spring:message></label></td>
    <td><input id="email" name="email" type="email" value="" /></td>
</tr>

<button type="submit" onclick="resetPass()">
    <spring:message code="message.resetPassword"></spring:message>
</button>
</div>

<br> 
<a href="<c:url value="registration.html" />">
    <spring:message code="label.form.loginSignUp"></spring:message>
</a>

<br>
<a href="<c:url value="login.html" />">
    <spring:message code="label.form.loginLink"></spring:message>
</a>
</div>
</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
function resetPass(){
    var email = $("#email").val();
    $.post("<c:url value="/user/resetPassword"></c:url>",{email: email} ,function(data){
        if(data.indexOf("MailError") > -1) {
            window.location.href = "<c:url value="/emailError.html"></c:url>";
        }
        else if(data.indexOf("InternalError") > -1){
            window.location.href = 
              "<c:url value="/login.html">
                <c:param name="message" value="Error Occurred"/>
              </c:url>";
        }
        else{
            window.location.href = "<c:url value="/login.html"></c:url>" + "?message=" + data;
        }
    });
}
</script>
</body>
</html>

We’ll enable the user to reset their password by adding a link to reset password in login.html:

Current Locale : ${pageContext.response.locale} 
<br> 
<a href="<c:url value="/user/registration" />">
    <spring:message code="label.form.loginSignUp"></spring:message>
</a>
<br> 
<a href="<c:url value="/forgotPassword.html" />">
    <spring:message code="message.resetPassword"></spring:message>
</a>

4. Create the PasswordResetToken

Next, we’ll create the new PasswordResetToken and send it via email to the user:

@RequestMapping(value = "/user/resetPassword", method = RequestMethod.POST)
public @ResponseBody String resetPassword(
  HttpServletRequest request, Model model, @RequestParam("email") String userEmail) 
  throws JsonProcessingException, NoSuchMessageException {
    
    User user = userService.findUserByEmail(userEmail);
    if (user == null) {
        return new ObjectMapper().writeValueAsString(
          messages.getMessage("message.userNotFound", null, request.getLocale()));
    }

    String token = UUID.randomUUID().toString();
    userService.createPasswordResetTokenForUser(user, token);
    String appUrl = 
      "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
    SimpleMailMessage email = constructResetTokenEmail(appUrl, request.getLocale(), token, user);
    mailSender.send(email);

    return new ObjectMapper().writeValueAsString(
      messages.getMessage("message.resetPasswordEmail", null, request.getLocale()));
}

And here is method constructResetTokenEmail() – used to send an email with the reset token:

private SimpleMailMessage constructResetTokenEmail(
  String contextPath, Locale locale, String token, User user) {
    String url = contextPath + "/user/changePassword?id=" + user.getId() + "&token=" + token;
    String message = messages.getMessage("message.resetPassword", null, locale);
    SimpleMailMessage email = new SimpleMailMessage();
    email.setTo(user.getEmail());
    email.setSubject("Reset Password");
    email.setText(message + " \r\n" + url);
    email.setFrom(env.getProperty("support.email"));
    return email;
}

5. Process the PasswordResetToken

The user gets the email with the unique link for resetting their password, and clicks the link:

@RequestMapping(value = "/user/changePassword", method = RequestMethod.GET)
public String changePassword(
  HttpServletRequest request, Model model, @RequestParam("id") long id, @RequestParam("token") String token) {
    Locale locale = request.getLocale();

    PasswordResetToken passToken = userService.getPasswordResetToken(token);
    User user = passToken.getUser();
    if (passToken == null || user.getId() != id) {
        String message = messages.getMessage("auth.message.invalidToken", null, locale);
        model.addAttribute("message", message);
        return "redirect:/login.html?lang=" + locale.getLanguage();
    }

    Calendar cal = Calendar.getInstance();
    if ((passToken.getExpiryDate().getTime() - cal.getTime().getTime()) <= 0) {
        model.addAttribute("message", messages.getMessage("auth.message.expired", null, locale));
        return "redirect:/login.html?lang=" + locale.getLanguage();
    }

    Authentication auth = new UsernamePasswordAuthenticationToken(
      user, null, userDetailsService.loadUserByUsername(user.getEmail()).getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(auth);

    return "redirect:/updatePassword.html?lang=" + locale.getLanguage();
}

As you can see – if the token is valid, the user will be authorized to change their password, and directed to a page to update their password.

6. Change Password

At this point, the user sees the simple Password Reset page – where the only possible option is to provide a new password:

6.1. updatePassword.html

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<%@ page session="false"%>
<html>
<head>
<link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet">
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title><spring:message code="message.updatePassword"></spring:message></title>
</head>
<body>
<sec:authorize access="hasRole('READ_PRIVILEGE')">
    <div class="container">
        <div class="span12">
            <h1>
                <spring:message code="message.resetYourPassword"></spring:message>
            </h1>
            <form:form action="user/savePassword" method="POST" enctype="utf8">
                <br>
                <tr>
                    <td><label>
                        <spring:message code="label.user.password"></spring:message>
                    </label></td>
                    <td><input id="pass" name="password" type="password" value="" /></td>
                </tr>
                <tr>
                    <td><label>
                        <spring:message code="label.user.confirmPass"></spring:message>
                    </label></td>
                    <td>
                        <input id="passConfirm" type="password" value="" />
                        <span id="error" class="alert alert-error" style="display:none">
                             <spring:message code="PasswordMatches.user"></spring:message>
                        </span>
                    </td>
                </tr>
                <br><br>
                <button type="submit">
                    <spring:message code="message.updatePassword"></spring:message>
                </button>
            </form:form>
        </div>
    </div>
    </sec:authorize>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
      $('form').on('submit', function(e){
        var valid = $("#pass").val() == $("#passConfirm").val();
        if(!valid) {
          e.preventDefault();
          $("#error").show();
        }
      });
    });
</script>   
</body>

</html>

6.2. Save User Password

Finally, when the previous form is submitted – the new user password is saved:

@RequestMapping(value = "/user/savePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('READ_PRIVILEGE')")
public String savePassword(
  HttpServletRequest request, Model model, @RequestParam("password") String password) {
    Locale locale = request.getLocale();

    User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    userService.changeUserPassword(user, password);
    model.addAttribute("message", messages.getMessage("message.resetPasswordSuc", null, locale));
    return "redirect:/login.html?lang=" + locale;
}

7. Conclusion

In this article we implemented a simple but very useful feature for a mature Authentication process – the option to reset your own password, as a user of the system.

The full implementation of this tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Security on Twitter - you can follow me there:


Spring Security – “Login and Registration Series”

Baeldung Weekly Review 8

$
0
0

I usually post about Dev stuff on Twitter - you can follow me there:

At the very beginning of 2014 I decided to track my reading habits and share the best stuff here, on Baeldung.

2014 has been quite the year, covering each week with a review. I’ve been doing a lot more reading to make sure I cover and curate stuff that has value and is actually worth reading.

Let me know in the comments if you’re finding my reviews interesting and useful.

Here we go…

1. Spring and Java

>> Value-Based Classes

A comprehensive guide to what value based classes mean in Java 8 (not much) and what will likely mean in Java 9 and beyond (a lot more).

>> Hibernate locking patterns – How does PESSIMISTIC_FORCE_INCREMENT Lock Mode work

The Hibernate Masterclass is moving forward, this time with a solid piece on pessimistic locking.

>> Why is my JVM having access to less memory than specified via -Xmx?

Deep dive into the JVM memory configuration options and how they translate to the runtime.

>> Using JDK 8 Streams to Convert Between Collections of Wrapped Objects and Collections of Wrapper Objects

An exploration of how to best leverage streams to deal with conversions between a value and a wrapper for that value.

>> Visual Testing With Selenium WebDriver

Just a little bit of UI testing can bring a whole lot of trust in the fact that your app is running the way it should, and WebDriver/Selenium is a fantastic tool for that.

>> JPA 2.1 – 12 features every developer should know

An solid overview of what JPA 2.1 brings to the table.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical and Musings

>> HTTP/2 is Done

I guess the title speaks for itself on this one.

>> Do It Either Way, We’ll Refactor It Later

A sensible and pragmatic mindset for designing an application. These kinds of architecture/design disagreements will come up in a team, so having the right kind of mindset makes a world of difference. That, and egoless programming (which is not as easy as it sounds).

>> What is Your Next Action?

A nuance of managing your TODO list better. Or I should say – my TODO list, since it’s something that I’m going to be mindful of and see if it makes a difference.

>> ConversationalStories

An important (but tricky) aspect to get right when doing any form of Agile – the importance of good ol’ dialog.

>> Why the hell not?

A different way to think about stuff.

>> Google and blogs: “Shit.”

This one is a bit meta, but it was certainly an interesting read to see what other bloggers experience in terms of traffic and trends.

3. Comics

And my favorite Dilberts of the week:

>> Your idea has already been tried

>> “The Taper”

>> Performance Feedback

4. Pick of the Week

Earlier this year I introduced the “Pick of the Week” section here in my “Weekly Review”. If you’re already on my email list – you got the pick already – hope you enjoyed it.

If not – you can share the review and unlock it right here:

 

I usually post about Dev stuff on Twitter - you can follow me there:

Viewing all 3450 articles
Browse latest View live