Merge branch 'master' of https://github.com/sanketmeghani/tutorials into sanketmeghani-master
This commit is contained in:
commit
d9b22f816a
@ -7,8 +7,7 @@ import org.junit.Test;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.*;
|
||||||
import static java.util.stream.Collectors.toSet;
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.core.IsNot.not;
|
import static org.hamcrest.core.IsNot.not;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
@ -22,7 +21,7 @@ public class ArrayListTest {
|
|||||||
List<String> xs = LongStream.range(0, 16)
|
List<String> xs = LongStream.range(0, 16)
|
||||||
.boxed()
|
.boxed()
|
||||||
.map(Long::toHexString)
|
.map(Long::toHexString)
|
||||||
.collect(toList());
|
.collect(toCollection(ArrayList::new));
|
||||||
stringsToSearch = new ArrayList<>(xs);
|
stringsToSearch = new ArrayList<>(xs);
|
||||||
stringsToSearch.addAll(xs);
|
stringsToSearch.addAll(xs);
|
||||||
}
|
}
|
||||||
@ -57,8 +56,8 @@ public class ArrayListTest {
|
|||||||
@Test
|
@Test
|
||||||
public void givenCollection_whenAddToArrayList_thenIsAdded() {
|
public void givenCollection_whenAddToArrayList_thenIsAdded() {
|
||||||
List<Long> xs = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
|
List<Long> xs = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
|
||||||
Collection<Long> ys = LongStream.range(4, 10).boxed().collect(toList());
|
LongStream.range(4, 10).boxed()
|
||||||
xs.addAll(0, ys);
|
.collect(collectingAndThen(toList(), ys -> xs.addAll(0, ys)));
|
||||||
|
|
||||||
assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(xs));
|
assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(xs));
|
||||||
}
|
}
|
||||||
@ -92,7 +91,7 @@ public class ArrayListTest {
|
|||||||
List<String> result = stringsToSearch
|
List<String> result = stringsToSearch
|
||||||
.stream()
|
.stream()
|
||||||
.filter(matchingStrings::contains)
|
.filter(matchingStrings::contains)
|
||||||
.collect(toList());
|
.collect(toCollection(ArrayList::new));
|
||||||
|
|
||||||
assertEquals(6, result.size());
|
assertEquals(6, result.size());
|
||||||
}
|
}
|
||||||
@ -107,7 +106,7 @@ public class ArrayListTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenIndex_whenRemove_thenCorrectElementRemoved() {
|
public void givenIndex_whenRemove_thenCorrectElementRemoved() {
|
||||||
List<Integer> xs = IntStream.range(0, 10).boxed().collect(toList());
|
List<Integer> xs = IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new));
|
||||||
Collections.reverse(xs);
|
Collections.reverse(xs);
|
||||||
|
|
||||||
xs.remove(0);
|
xs.remove(0);
|
||||||
@ -119,7 +118,7 @@ public class ArrayListTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenListIterator_whenReverseTraversal_thenRetrieveElementsInOppositeOrder() {
|
public void givenListIterator_whenReverseTraversal_thenRetrieveElementsInOppositeOrder() {
|
||||||
List<Integer> xs = IntStream.range(0, 10).boxed().collect(toList());
|
List<Integer> xs = IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new));
|
||||||
ListIterator<Integer> it = xs.listIterator(xs.size());
|
ListIterator<Integer> it = xs.listIterator(xs.size());
|
||||||
List<Integer> result = new ArrayList<>(xs.size());
|
List<Integer> result = new ArrayList<>(xs.size());
|
||||||
while (it.hasPrevious()) {
|
while (it.hasPrevious()) {
|
||||||
|
@ -5,63 +5,59 @@ import java.util.HashSet;
|
|||||||
|
|
||||||
public class ComplexClass {
|
public class ComplexClass {
|
||||||
|
|
||||||
private ArrayList<?> genericArrayList;
|
private ArrayList<?> genericArrayList;
|
||||||
private HashSet<Integer> integerHashSet;
|
private HashSet<Integer> integerHashSet;
|
||||||
|
|
||||||
public ComplexClass(ArrayList<?> genericArrayList,
|
public ComplexClass(ArrayList<?> genericArrayList, HashSet<Integer> integerHashSet) {
|
||||||
HashSet<Integer> integerHashSet) {
|
super();
|
||||||
super();
|
this.genericArrayList = genericArrayList;
|
||||||
this.genericArrayList = genericArrayList;
|
this.integerHashSet = integerHashSet;
|
||||||
this.integerHashSet = integerHashSet;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime
|
result = prime * result + ((genericArrayList == null) ? 0 : genericArrayList.hashCode());
|
||||||
* result
|
result = prime * result + ((integerHashSet == null) ? 0 : integerHashSet.hashCode());
|
||||||
+ ((genericArrayList == null) ? 0 : genericArrayList.hashCode());
|
return result;
|
||||||
result = prime * result
|
}
|
||||||
+ ((integerHashSet == null) ? 0 : integerHashSet.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
return false;
|
return false;
|
||||||
if (!(obj instanceof ComplexClass))
|
if (!(obj instanceof ComplexClass))
|
||||||
return false;
|
return false;
|
||||||
ComplexClass other = (ComplexClass) obj;
|
ComplexClass other = (ComplexClass) obj;
|
||||||
if (genericArrayList == null) {
|
if (genericArrayList == null) {
|
||||||
if (other.genericArrayList != null)
|
if (other.genericArrayList != null)
|
||||||
return false;
|
return false;
|
||||||
} else if (!genericArrayList.equals(other.genericArrayList))
|
} else if (!genericArrayList.equals(other.genericArrayList))
|
||||||
return false;
|
return false;
|
||||||
if (integerHashSet == null) {
|
if (integerHashSet == null) {
|
||||||
if (other.integerHashSet != null)
|
if (other.integerHashSet != null)
|
||||||
return false;
|
return false;
|
||||||
} else if (!integerHashSet.equals(other.integerHashSet))
|
} else if (!integerHashSet.equals(other.integerHashSet))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ArrayList<?> getGenericArrayList() {
|
protected ArrayList<?> getGenericArrayList() {
|
||||||
return genericArrayList;
|
return genericArrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setGenericArrayList(ArrayList<?> genericArrayList) {
|
protected void setGenericArrayList(ArrayList<?> genericArrayList) {
|
||||||
this.genericArrayList = genericArrayList;
|
this.genericArrayList = genericArrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HashSet<Integer> getIntegerHashSet() {
|
protected HashSet<Integer> getIntegerHashSet() {
|
||||||
return integerHashSet;
|
return integerHashSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setIntegerHashSet(HashSet<Integer> integerHashSet) {
|
protected void setIntegerHashSet(HashSet<Integer> integerHashSet) {
|
||||||
this.integerHashSet = integerHashSet;
|
this.integerHashSet = integerHashSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,53 +2,53 @@ package org.baeldung.equalshashcode.entities;
|
|||||||
|
|
||||||
public class PrimitiveClass {
|
public class PrimitiveClass {
|
||||||
|
|
||||||
private boolean primitiveBoolean;
|
private boolean primitiveBoolean;
|
||||||
private int primitiveInt;
|
private int primitiveInt;
|
||||||
|
|
||||||
public PrimitiveClass(boolean primitiveBoolean, int primitiveInt) {
|
public PrimitiveClass(boolean primitiveBoolean, int primitiveInt) {
|
||||||
super();
|
super();
|
||||||
this.primitiveBoolean = primitiveBoolean;
|
this.primitiveBoolean = primitiveBoolean;
|
||||||
this.primitiveInt = primitiveInt;
|
this.primitiveInt = primitiveInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isPrimitiveBoolean() {
|
protected boolean isPrimitiveBoolean() {
|
||||||
return primitiveBoolean;
|
return primitiveBoolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + (primitiveBoolean ? 1231 : 1237);
|
result = prime * result + (primitiveBoolean ? 1231 : 1237);
|
||||||
result = prime * result + primitiveInt;
|
result = prime * result + primitiveInt;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
PrimitiveClass other = (PrimitiveClass) obj;
|
PrimitiveClass other = (PrimitiveClass) obj;
|
||||||
if (primitiveBoolean != other.primitiveBoolean)
|
if (primitiveBoolean != other.primitiveBoolean)
|
||||||
return false;
|
return false;
|
||||||
if (primitiveInt != other.primitiveInt)
|
if (primitiveInt != other.primitiveInt)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setPrimitiveBoolean(boolean primitiveBoolean) {
|
protected void setPrimitiveBoolean(boolean primitiveBoolean) {
|
||||||
this.primitiveBoolean = primitiveBoolean;
|
this.primitiveBoolean = primitiveBoolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getPrimitiveInt() {
|
protected int getPrimitiveInt() {
|
||||||
return primitiveInt;
|
return primitiveInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setPrimitiveInt(int primitiveInt) {
|
protected void setPrimitiveInt(int primitiveInt) {
|
||||||
this.primitiveInt = primitiveInt;
|
this.primitiveInt = primitiveInt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,62 +1,60 @@
|
|||||||
package org.baeldung.equalshashcode.entities;
|
package org.baeldung.equalshashcode.entities;
|
||||||
|
|
||||||
public class Rectangle extends Shape {
|
public class Rectangle extends Shape {
|
||||||
private double width;
|
private double width;
|
||||||
private double length;
|
private double length;
|
||||||
|
|
||||||
public Rectangle(double width, double length) {
|
public Rectangle(double width, double length) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double area() {
|
public double area() {
|
||||||
// A = w * l
|
// A = w * l
|
||||||
return width * length;
|
return width * length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double perimeter() {
|
public double perimeter() {
|
||||||
// P = 2(w + l)
|
// P = 2(w + l)
|
||||||
return 2 * (width + length);
|
return 2 * (width + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
long temp;
|
long temp;
|
||||||
temp = Double.doubleToLongBits(length);
|
temp = Double.doubleToLongBits(length);
|
||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
temp = Double.doubleToLongBits(width);
|
temp = Double.doubleToLongBits(width);
|
||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
Rectangle other = (Rectangle) obj;
|
Rectangle other = (Rectangle) obj;
|
||||||
if (Double.doubleToLongBits(length) != Double
|
if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length))
|
||||||
.doubleToLongBits(other.length))
|
return false;
|
||||||
return false;
|
if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width))
|
||||||
if (Double.doubleToLongBits(width) != Double
|
return false;
|
||||||
.doubleToLongBits(other.width))
|
return true;
|
||||||
return false;
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected double getWidth() {
|
protected double getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double getLength() {
|
protected double getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package org.baeldung.equalshashcode.entities;
|
package org.baeldung.equalshashcode.entities;
|
||||||
|
|
||||||
public abstract class Shape {
|
public abstract class Shape {
|
||||||
public abstract double area();
|
public abstract double area();
|
||||||
|
|
||||||
public abstract double perimeter();
|
public abstract double perimeter();
|
||||||
}
|
}
|
||||||
|
@ -4,44 +4,55 @@ import java.awt.Color;
|
|||||||
|
|
||||||
public class Square extends Rectangle {
|
public class Square extends Rectangle {
|
||||||
|
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
public Square(double width, Color color) {
|
public Square(double width, Color color) {
|
||||||
super(width, width);
|
super(width, width);
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/* (non-Javadoc)
|
||||||
public int hashCode() {
|
* @see java.lang.Object#hashCode()
|
||||||
final int prime = 31;
|
*/
|
||||||
int result = super.hashCode();
|
@Override
|
||||||
result = prime * result + ((color == null) ? 0 : color.hashCode());
|
public int hashCode() {
|
||||||
return result;
|
final int prime = 31;
|
||||||
}
|
int result = super.hashCode();
|
||||||
|
result = prime * result + ((color == null) ? 0 : color.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
/* (non-Javadoc)
|
||||||
public boolean equals(Object obj) {
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
if (this == obj)
|
*/
|
||||||
return true;
|
@Override
|
||||||
if (!super.equals(obj))
|
public boolean equals(Object obj) {
|
||||||
return false;
|
if (this == obj) {
|
||||||
if (getClass() != obj.getClass())
|
return true;
|
||||||
return false;
|
}
|
||||||
Square other = (Square) obj;
|
if (!super.equals(obj)) {
|
||||||
if (color == null) {
|
return false;
|
||||||
if (other.color != null)
|
}
|
||||||
return false;
|
if (!(obj instanceof Square)) {
|
||||||
} else if (!color.equals(other.color))
|
return false;
|
||||||
return false;
|
}
|
||||||
return true;
|
Square other = (Square) obj;
|
||||||
}
|
if (color == null) {
|
||||||
|
if (other.color != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!color.equals(other.color)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected Color getColor() {
|
protected Color getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setColor(Color color) {
|
protected void setColor(Color color) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,32 +8,27 @@ import org.junit.Test;
|
|||||||
|
|
||||||
public class ComplexClassTest {
|
public class ComplexClassTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualsAndHashcodes() {
|
public void testEqualsAndHashcodes() {
|
||||||
|
|
||||||
ArrayList<String> strArrayList = new ArrayList<String>();
|
ArrayList<String> strArrayList = new ArrayList<String>();
|
||||||
strArrayList.add("abc");
|
strArrayList.add("abc");
|
||||||
strArrayList.add("def");
|
strArrayList.add("def");
|
||||||
ComplexClass aObject = new ComplexClass(strArrayList, new HashSet<Integer>(45,67));
|
ComplexClass aObject = new ComplexClass(strArrayList, new HashSet<Integer>(45, 67));
|
||||||
ComplexClass bObject = new ComplexClass(strArrayList, new HashSet<Integer>(45,67));
|
ComplexClass bObject = new ComplexClass(strArrayList, new HashSet<Integer>(45, 67));
|
||||||
ComplexClass cObject = new ComplexClass(strArrayList, new HashSet<Integer>(45,67));
|
|
||||||
|
|
||||||
ArrayList<String> strArrayListD = new ArrayList<String>();
|
ArrayList<String> strArrayListD = new ArrayList<String>();
|
||||||
strArrayListD.add("lmn");
|
strArrayListD.add("lmn");
|
||||||
strArrayListD.add("pqr");
|
strArrayListD.add("pqr");
|
||||||
ComplexClass dObject = new ComplexClass(strArrayListD, new HashSet<Integer>(45,67));
|
ComplexClass dObject = new ComplexClass(strArrayListD, new HashSet<Integer>(45, 67));
|
||||||
|
|
||||||
// equals()
|
// equals()
|
||||||
Assert.assertTrue(aObject.equals(aObject));
|
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
|
||||||
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
|
// hashCode()
|
||||||
Assert.assertTrue(aObject.equals(bObject));
|
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
|
||||||
Assert.assertTrue(bObject.equals(cObject));
|
// non-equal objects are not equals() and have different hashCode()
|
||||||
Assert.assertTrue(aObject.equals(cObject));
|
Assert.assertFalse(aObject.equals(dObject));
|
||||||
// hashCode()
|
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
|
||||||
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
|
}
|
||||||
// non-equal objects are not equals() and have different hashCode()
|
|
||||||
Assert.assertFalse(aObject.equals(dObject));
|
|
||||||
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,25 +5,20 @@ import org.junit.Test;
|
|||||||
|
|
||||||
public class PrimitiveClassTest {
|
public class PrimitiveClassTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTwoEqualsObjects() {
|
public void testTwoEqualsObjects() {
|
||||||
|
|
||||||
PrimitiveClass aObject = new PrimitiveClass(false, 2);
|
PrimitiveClass aObject = new PrimitiveClass(false, 2);
|
||||||
PrimitiveClass bObject = new PrimitiveClass(false, 2);
|
PrimitiveClass bObject = new PrimitiveClass(false, 2);
|
||||||
PrimitiveClass cObject = new PrimitiveClass(false, 2);
|
PrimitiveClass dObject = new PrimitiveClass(true, 2);
|
||||||
PrimitiveClass dObject = new PrimitiveClass(true, 2);
|
|
||||||
|
|
||||||
// equals()
|
// equals()
|
||||||
Assert.assertTrue(aObject.equals(aObject));
|
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
|
||||||
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
|
// hashCode()
|
||||||
Assert.assertTrue(aObject.equals(bObject));
|
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
|
||||||
Assert.assertTrue(bObject.equals(cObject));
|
// non-equal objects are not equals() and have different hashCode()
|
||||||
Assert.assertTrue(aObject.equals(cObject));
|
Assert.assertFalse(aObject.equals(dObject));
|
||||||
// hashCode()
|
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
|
||||||
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
|
}
|
||||||
// non-equal objects are not equals() and have different hashCode()
|
|
||||||
Assert.assertFalse(aObject.equals(dObject));
|
|
||||||
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,26 +7,21 @@ import org.junit.Test;
|
|||||||
|
|
||||||
public class SquareClassTest {
|
public class SquareClassTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualsAndHashcodes() {
|
public void testEqualsAndHashcodes() {
|
||||||
|
|
||||||
Square aObject = new Square(10, Color.BLUE);
|
Square aObject = new Square(10, Color.BLUE);
|
||||||
Square bObject = new Square(10, Color.BLUE);
|
Square bObject = new Square(10, Color.BLUE);
|
||||||
Square cObject = new Square(10, Color.BLUE);
|
|
||||||
|
|
||||||
Square dObject = new Square(20, Color.BLUE);
|
Square dObject = new Square(20, Color.BLUE);
|
||||||
|
|
||||||
// equals()
|
// equals()
|
||||||
Assert.assertTrue(aObject.equals(aObject));
|
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
|
||||||
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
|
// hashCode()
|
||||||
Assert.assertTrue(aObject.equals(bObject));
|
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
|
||||||
Assert.assertTrue(bObject.equals(cObject));
|
// non-equal objects are not equals() and have different hashCode()
|
||||||
Assert.assertTrue(aObject.equals(cObject));
|
Assert.assertFalse(aObject.equals(dObject));
|
||||||
// hashCode()
|
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
|
||||||
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
|
}
|
||||||
// non-equal objects are not equals() and have different hashCode()
|
|
||||||
Assert.assertFalse(aObject.equals(dObject));
|
|
||||||
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS `department` (
|
||||||
|
|
||||||
|
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`name` varchar(20)
|
||||||
|
|
||||||
|
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;
|
||||||
|
|
||||||
|
ALTER TABLE `employee` ADD `dept_id` int AFTER `email`;
|
@ -23,6 +23,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.5.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source>
|
||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
|
102
java-cassandra/pom.xml
Normal file
102
java-cassandra/pom.xml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>cassandra-java-client</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>cassandra-java-client</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
||||||
|
<!-- logging -->
|
||||||
|
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||||
|
<logback.version>1.1.7</logback.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<mockito.version>1.10.19</mockito.version>
|
||||||
|
<testng.version>6.8</testng.version>
|
||||||
|
<assertj.version>3.5.1</assertj.version>
|
||||||
|
|
||||||
|
<!-- maven plugins -->
|
||||||
|
<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
|
||||||
|
|
||||||
|
<!-- Cassandra -->
|
||||||
|
<cassandra-driver-core.version>3.1.0</cassandra-driver-core.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Cassandra -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.cassandra</groupId>
|
||||||
|
<artifactId>cassandra-driver-core</artifactId>
|
||||||
|
<version>${cassandra-driver-core.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.cassandraunit/cassandra-unit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cassandraunit</groupId>
|
||||||
|
<artifactId>cassandra-unit</artifactId>
|
||||||
|
<version>3.0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- This guava version is required for cassandra-unit 3.0.0.1 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>19.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- logging -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${org.slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
<!-- <scope>runtime</scope> -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
|
<version>${org.slf4j.version}</version>
|
||||||
|
<!-- <scope>runtime</scope> --> <!-- some spring dependencies need to compile against jcl -->
|
||||||
|
</dependency>
|
||||||
|
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>log4j-over-slf4j</artifactId>
|
||||||
|
<version>${org.slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>java-cassandra</finalName>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.cassandra.java.client;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.baeldung.cassandra.java.client.domain.Book;
|
||||||
|
import com.baeldung.cassandra.java.client.repository.BookRepository;
|
||||||
|
import com.baeldung.cassandra.java.client.repository.KeyspaceRepository;
|
||||||
|
import com.datastax.driver.core.Session;
|
||||||
|
import com.datastax.driver.core.utils.UUIDs;
|
||||||
|
|
||||||
|
public class CassandraClient {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CassandraClient.class);
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
CassandraConnector connector = new CassandraConnector();
|
||||||
|
connector.connect("127.0.0.1", null);
|
||||||
|
Session session = connector.getSession();
|
||||||
|
|
||||||
|
KeyspaceRepository sr = new KeyspaceRepository(session);
|
||||||
|
sr.createKeyspace("library", "SimpleStrategy", 1);
|
||||||
|
sr.useKeyspace("library");
|
||||||
|
|
||||||
|
BookRepository br = new BookRepository(session);
|
||||||
|
br.createTable();
|
||||||
|
br.alterTablebooks("publisher", "text");
|
||||||
|
|
||||||
|
br.createTableBooksByTitle();
|
||||||
|
|
||||||
|
Book book = new Book(UUIDs.timeBased(), "Effective Java", "Joshua Bloch", "Programming");
|
||||||
|
br.insertBookBatch(book);
|
||||||
|
|
||||||
|
br.selectAll().forEach(o -> LOG.info("Title in books: " + o.getTitle()));
|
||||||
|
br.selectAllBookByTitle().forEach(o -> LOG.info("Title in booksByTitle: " + o.getTitle()));
|
||||||
|
|
||||||
|
br.deletebookByTitle("Effective Java");
|
||||||
|
br.deleteTable("books");
|
||||||
|
br.deleteTable("booksByTitle");
|
||||||
|
|
||||||
|
sr.deleteKeyspace("library");
|
||||||
|
|
||||||
|
connector.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.baeldung.cassandra.java.client;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.datastax.driver.core.Cluster;
|
||||||
|
import com.datastax.driver.core.Cluster.Builder;
|
||||||
|
import com.datastax.driver.core.Host;
|
||||||
|
import com.datastax.driver.core.Metadata;
|
||||||
|
import com.datastax.driver.core.Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This is an implementation of a simple Java client.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CassandraConnector {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CassandraConnector.class);
|
||||||
|
|
||||||
|
private Cluster cluster;
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
public void connect(final String node, final Integer port) {
|
||||||
|
|
||||||
|
Builder b = Cluster.builder().addContactPoint(node);
|
||||||
|
|
||||||
|
if (port != null) {
|
||||||
|
b.withPort(port);
|
||||||
|
}
|
||||||
|
cluster = b.build();
|
||||||
|
|
||||||
|
Metadata metadata = cluster.getMetadata();
|
||||||
|
LOG.info("Cluster name: " + metadata.getClusterName());
|
||||||
|
|
||||||
|
for (Host host : metadata.getAllHosts()) {
|
||||||
|
LOG.info("Datacenter: " + host.getDatacenter() + " Host: " + host.getAddress() + " Rack: " + host.getRack());
|
||||||
|
}
|
||||||
|
|
||||||
|
session = cluster.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Session getSession() {
|
||||||
|
return this.session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
session.close();
|
||||||
|
cluster.close();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.baeldung.cassandra.java.client.domain;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Book {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String author;
|
||||||
|
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
private String publisher;
|
||||||
|
|
||||||
|
Book() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Book(UUID id, String title, String author, String subject) {
|
||||||
|
this.id = id;
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(String author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubject(String subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPublisher() {
|
||||||
|
return publisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublisher(String publisher) {
|
||||||
|
this.publisher = publisher;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,177 @@
|
|||||||
|
package com.baeldung.cassandra.java.client.repository;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.cassandra.java.client.domain.Book;
|
||||||
|
import com.datastax.driver.core.ResultSet;
|
||||||
|
import com.datastax.driver.core.Row;
|
||||||
|
import com.datastax.driver.core.Session;
|
||||||
|
|
||||||
|
public class BookRepository {
|
||||||
|
|
||||||
|
private static final String TABLE_NAME = "books";
|
||||||
|
|
||||||
|
private static final String TABLE_NAME_BY_TITLE = TABLE_NAME + "ByTitle";
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
public BookRepository(Session session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the books table.
|
||||||
|
*/
|
||||||
|
public void createTable() {
|
||||||
|
StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME).append("(").append("id uuid PRIMARY KEY, ").append("title text,").append("author text,").append("subject text);");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the books table.
|
||||||
|
*/
|
||||||
|
public void createTableBooksByTitle() {
|
||||||
|
StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME_BY_TITLE).append("(").append("id uuid, ").append("title text,").append("PRIMARY KEY (title, id));");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alters the table books and adds an extra column.
|
||||||
|
*/
|
||||||
|
public void alterTablebooks(String columnName, String columnType) {
|
||||||
|
StringBuilder sb = new StringBuilder("ALTER TABLE ").append(TABLE_NAME).append(" ADD ").append(columnName).append(" ").append(columnType).append(";");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a row in the table books.
|
||||||
|
*
|
||||||
|
* @param book
|
||||||
|
*/
|
||||||
|
public void insertbook(Book book) {
|
||||||
|
StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME).append("(id, title, author, subject) ").append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("', '").append(book.getAuthor()).append("', '")
|
||||||
|
.append(book.getSubject()).append("');");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a row in the table booksByTitle.
|
||||||
|
* @param book
|
||||||
|
*/
|
||||||
|
public void insertbookByTitle(Book book) {
|
||||||
|
StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME_BY_TITLE).append("(id, title) ").append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("');");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a book into two identical tables using a batch query.
|
||||||
|
*
|
||||||
|
* @param book
|
||||||
|
*/
|
||||||
|
public void insertBookBatch(Book book) {
|
||||||
|
StringBuilder sb = new StringBuilder("BEGIN BATCH ")
|
||||||
|
.append("INSERT INTO ").append(TABLE_NAME).append("(id, title, author, subject) ")
|
||||||
|
.append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("', '").append(book.getAuthor()).append("', '")
|
||||||
|
.append(book.getSubject()).append("');")
|
||||||
|
.append("INSERT INTO ").append(TABLE_NAME_BY_TITLE).append("(id, title) ")
|
||||||
|
.append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("');")
|
||||||
|
.append("APPLY BATCH;");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select book by id.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Book selectByTitle(String title) {
|
||||||
|
StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME_BY_TITLE).append(" WHERE title = '").append(title).append("';");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
|
||||||
|
ResultSet rs = session.execute(query);
|
||||||
|
|
||||||
|
List<Book> books = new ArrayList<Book>();
|
||||||
|
|
||||||
|
for (Row r : rs) {
|
||||||
|
Book s = new Book(r.getUUID("id"), r.getString("title"), null, null);
|
||||||
|
books.add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return books.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select all books from books
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<Book> selectAll() {
|
||||||
|
StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
ResultSet rs = session.execute(query);
|
||||||
|
|
||||||
|
List<Book> books = new ArrayList<Book>();
|
||||||
|
|
||||||
|
for (Row r : rs) {
|
||||||
|
Book book = new Book(r.getUUID("id"), r.getString("title"), r.getString("author"), r.getString("subject"));
|
||||||
|
books.add(book);
|
||||||
|
}
|
||||||
|
return books;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select all books from booksByTitle
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<Book> selectAllBookByTitle() {
|
||||||
|
StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME_BY_TITLE);
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
ResultSet rs = session.execute(query);
|
||||||
|
|
||||||
|
List<Book> books = new ArrayList<Book>();
|
||||||
|
|
||||||
|
for (Row r : rs) {
|
||||||
|
Book book = new Book(r.getUUID("id"), r.getString("title"), null, null);
|
||||||
|
books.add(book);
|
||||||
|
}
|
||||||
|
return books;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a book by title.
|
||||||
|
*/
|
||||||
|
public void deletebookByTitle(String title) {
|
||||||
|
StringBuilder sb = new StringBuilder("DELETE FROM ").append(TABLE_NAME_BY_TITLE).append(" WHERE title = '").append(title).append("';");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete table.
|
||||||
|
*
|
||||||
|
* @param tableName the name of the table to delete.
|
||||||
|
*/
|
||||||
|
public void deleteTable(String tableName) {
|
||||||
|
StringBuilder sb = new StringBuilder("DROP TABLE IF EXISTS ").append(tableName);
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.cassandra.java.client.repository;
|
||||||
|
|
||||||
|
import com.datastax.driver.core.Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository to handle the Cassandra schema.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class KeyspaceRepository {
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
public KeyspaceRepository(Session session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used to create any keyspace - schema.
|
||||||
|
*
|
||||||
|
* @param schemaName the name of the schema.
|
||||||
|
* @param replicatioonStrategy the replication strategy.
|
||||||
|
* @param numberOfReplicas the number of replicas.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void createKeyspace(String keyspaceName, String replicatioonStrategy, int numberOfReplicas) {
|
||||||
|
StringBuilder sb = new StringBuilder("CREATE KEYSPACE IF NOT EXISTS ").append(keyspaceName).append(" WITH replication = {").append("'class':'").append(replicatioonStrategy).append("','replication_factor':").append(numberOfReplicas).append("};");
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void useKeyspace(String keyspace) {
|
||||||
|
session.execute("USE " + keyspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used to delete the specified schema.
|
||||||
|
* It results in the immediate, irreversable removal of the keyspace, including all tables and data contained in the keyspace.
|
||||||
|
*
|
||||||
|
* @param schemaName the name of the keyspace to delete.
|
||||||
|
*/
|
||||||
|
public void deleteKeyspace(String keyspaceName) {
|
||||||
|
StringBuilder sb = new StringBuilder("DROP KEYSPACE ").append(keyspaceName);
|
||||||
|
|
||||||
|
final String query = sb.toString();
|
||||||
|
|
||||||
|
session.execute(query);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,174 @@
|
|||||||
|
package com.baeldung.cassandra.java.client.repository;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
|
import org.apache.thrift.transport.TTransportException;
|
||||||
|
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.cassandra.java.client.CassandraConnector;
|
||||||
|
import com.baeldung.cassandra.java.client.domain.Book;
|
||||||
|
import com.datastax.driver.core.ResultSet;
|
||||||
|
import com.datastax.driver.core.Session;
|
||||||
|
import com.datastax.driver.core.exceptions.InvalidQueryException;
|
||||||
|
import com.datastax.driver.core.utils.UUIDs;
|
||||||
|
|
||||||
|
public class BookRepositoryIntegrationTest {
|
||||||
|
|
||||||
|
private KeyspaceRepository schemaRepository;
|
||||||
|
|
||||||
|
private BookRepository bookRepository;
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
final String KEYSPACE_NAME = "testLibrary";
|
||||||
|
final String BOOKS = "books";
|
||||||
|
final String BOOKS_BY_TITLE = "booksByTitle";
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException {
|
||||||
|
// Start an embedded Cassandra Server
|
||||||
|
EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void connect() {
|
||||||
|
CassandraConnector client = new CassandraConnector();
|
||||||
|
client.connect("127.0.0.1", 9142);
|
||||||
|
this.session = client.getSession();
|
||||||
|
schemaRepository = new KeyspaceRepository(session);
|
||||||
|
schemaRepository.createKeyspace(KEYSPACE_NAME, "SimpleStrategy", 1);
|
||||||
|
schemaRepository.useKeyspace(KEYSPACE_NAME);
|
||||||
|
bookRepository = new BookRepository(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreatingATable_thenCreatedCorrectly() {
|
||||||
|
bookRepository.deleteTable(BOOKS);
|
||||||
|
bookRepository.createTable();
|
||||||
|
|
||||||
|
ResultSet result = session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";");
|
||||||
|
|
||||||
|
// Collect all the column names in one list.
|
||||||
|
List<String> columnNames = result.getColumnDefinitions().asList().stream().map(cl -> cl.getName()).collect(Collectors.toList());
|
||||||
|
assertEquals(columnNames.size(), 4);
|
||||||
|
assertTrue(columnNames.contains("id"));
|
||||||
|
assertTrue(columnNames.contains("title"));
|
||||||
|
assertTrue(columnNames.contains("author"));
|
||||||
|
assertTrue(columnNames.contains("subject"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAlteringTable_thenAddedColumnExists() {
|
||||||
|
bookRepository.deleteTable(BOOKS);
|
||||||
|
bookRepository.createTable();
|
||||||
|
|
||||||
|
bookRepository.alterTablebooks("publisher", "text");
|
||||||
|
|
||||||
|
ResultSet result = session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";");
|
||||||
|
|
||||||
|
boolean columnExists = result.getColumnDefinitions().asList().stream().anyMatch(cl -> cl.getName().equals("publisher"));
|
||||||
|
assertTrue(columnExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingANewBook_thenBookExists() {
|
||||||
|
bookRepository.deleteTable(BOOKS_BY_TITLE);
|
||||||
|
bookRepository.createTableBooksByTitle();
|
||||||
|
|
||||||
|
String title = "Effective Java";
|
||||||
|
String author = "Joshua Bloch";
|
||||||
|
Book book = new Book(UUIDs.timeBased(), title, author, "Programming");
|
||||||
|
bookRepository.insertbookByTitle(book);
|
||||||
|
|
||||||
|
Book savedBook = bookRepository.selectByTitle(title);
|
||||||
|
assertEquals(book.getTitle(), savedBook.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddingANewBookBatch_ThenBookAddedInAllTables() {
|
||||||
|
// Create table books
|
||||||
|
bookRepository.deleteTable(BOOKS);
|
||||||
|
bookRepository.createTable();
|
||||||
|
|
||||||
|
// Create table booksByTitle
|
||||||
|
bookRepository.deleteTable(BOOKS_BY_TITLE);
|
||||||
|
bookRepository.createTableBooksByTitle();
|
||||||
|
|
||||||
|
String title = "Effective Java";
|
||||||
|
String author = "Joshua Bloch";
|
||||||
|
Book book = new Book(UUIDs.timeBased(), title, author, "Programming");
|
||||||
|
bookRepository.insertBookBatch(book);
|
||||||
|
|
||||||
|
List<Book> books = bookRepository.selectAll();
|
||||||
|
|
||||||
|
assertEquals(1, books.size());
|
||||||
|
assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Effective Java")));
|
||||||
|
|
||||||
|
List<Book> booksByTitle = bookRepository.selectAllBookByTitle();
|
||||||
|
|
||||||
|
assertEquals(1, booksByTitle.size());
|
||||||
|
assertTrue(booksByTitle.stream().anyMatch(b -> b.getTitle().equals("Effective Java")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSelectingAll_thenReturnAllRecords() {
|
||||||
|
bookRepository.deleteTable(BOOKS);
|
||||||
|
bookRepository.createTable();
|
||||||
|
|
||||||
|
Book book = new Book(UUIDs.timeBased(), "Effective Java", "Joshua Bloch", "Programming");
|
||||||
|
bookRepository.insertbook(book);
|
||||||
|
|
||||||
|
book = new Book(UUIDs.timeBased(), "Clean Code", "Robert C. Martin", "Programming");
|
||||||
|
bookRepository.insertbook(book);
|
||||||
|
|
||||||
|
List<Book> books = bookRepository.selectAll();
|
||||||
|
|
||||||
|
assertEquals(2, books.size());
|
||||||
|
assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Effective Java")));
|
||||||
|
assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Clean Code")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeletingABookByTitle_thenBookIsDeleted() {
|
||||||
|
bookRepository.deleteTable(BOOKS_BY_TITLE);
|
||||||
|
bookRepository.createTableBooksByTitle();
|
||||||
|
|
||||||
|
Book book = new Book(UUIDs.timeBased(), "Effective Java", "Joshua Bloch", "Programming");
|
||||||
|
bookRepository.insertbookByTitle(book);
|
||||||
|
|
||||||
|
book = new Book(UUIDs.timeBased(), "Clean Code", "Robert C. Martin", "Programming");
|
||||||
|
bookRepository.insertbookByTitle(book);
|
||||||
|
|
||||||
|
bookRepository.deletebookByTitle("Clean Code");
|
||||||
|
|
||||||
|
List<Book> books = bookRepository.selectAllBookByTitle();
|
||||||
|
assertEquals(1, books.size());
|
||||||
|
assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Effective Java")));
|
||||||
|
assertFalse(books.stream().anyMatch(b -> b.getTitle().equals("Clean Code")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidQueryException.class)
|
||||||
|
public void whenDeletingATable_thenUnconfiguredTable() {
|
||||||
|
bookRepository.createTable();
|
||||||
|
bookRepository.deleteTable(BOOKS);
|
||||||
|
|
||||||
|
session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanup() {
|
||||||
|
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.baeldung.cassandra.java.client.repository;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
|
import org.apache.thrift.transport.TTransportException;
|
||||||
|
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import com.baeldung.cassandra.java.client.CassandraConnector;
|
||||||
|
import com.datastax.driver.core.ResultSet;
|
||||||
|
import com.datastax.driver.core.Session;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class KeyspaceRepositoryIntegrationTest {
|
||||||
|
|
||||||
|
private KeyspaceRepository schemaRepository;
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException {
|
||||||
|
// Start an embedded Cassandra Server
|
||||||
|
EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void connect() {
|
||||||
|
CassandraConnector client = new CassandraConnector();
|
||||||
|
client.connect("127.0.0.1", 9142);
|
||||||
|
this.session = client.getSession();
|
||||||
|
schemaRepository = new KeyspaceRepository(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreatingAKeyspace_thenCreated() {
|
||||||
|
String keyspaceName = "testBaeldungKeyspace";
|
||||||
|
schemaRepository.createKeyspace(keyspaceName, "SimpleStrategy", 1);
|
||||||
|
|
||||||
|
// ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces WHERE keyspace_name = 'testBaeldungKeyspace';");
|
||||||
|
|
||||||
|
ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces;");
|
||||||
|
|
||||||
|
// Check if the Keyspace exists in the returned keyspaces.
|
||||||
|
List<String> matchedKeyspaces = result.all().stream().filter(r -> r.getString(0).equals(keyspaceName.toLowerCase())).map(r -> r.getString(0)).collect(Collectors.toList());
|
||||||
|
assertEquals(matchedKeyspaces.size(), 1);
|
||||||
|
assertTrue(matchedKeyspaces.get(0).equals(keyspaceName.toLowerCase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDeletingAKeyspace_thenDoesNotExist() {
|
||||||
|
String keyspaceName = "testBaeldungKeyspace";
|
||||||
|
|
||||||
|
// schemaRepository.createKeyspace(keyspaceName, "SimpleStrategy", 1);
|
||||||
|
schemaRepository.deleteKeyspace(keyspaceName);
|
||||||
|
|
||||||
|
ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces;");
|
||||||
|
boolean isKeyspaceCreated = result.all().stream().anyMatch(r -> r.getString(0).equals(keyspaceName.toLowerCase()));
|
||||||
|
assertFalse(isKeyspaceCreated);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanup() {
|
||||||
|
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||||
|
}
|
||||||
|
}
|
2
pom.xml
2
pom.xml
@ -129,7 +129,7 @@
|
|||||||
<module>redis</module>
|
<module>redis</module>
|
||||||
|
|
||||||
<module>xstream</module>
|
<module>xstream</module>
|
||||||
|
<module>java-cassandra</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package org.baeldung.persistence.multiple.dao.user;
|
||||||
|
|
||||||
|
import org.baeldung.persistence.multiple.model.user.Possession;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface PossessionRepository extends JpaRepository<Possession, Long> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package org.baeldung.persistence.multiple.model.user;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(schema = "spring_jpa_user")
|
||||||
|
public class Possession {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Possession() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Possession(final String name) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = (prime * result) + (int) (id ^ (id >>> 32));
|
||||||
|
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final Possession other = (Possession) obj;
|
||||||
|
if (id != other.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!name.equals(other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Possesion [id=").append(id).append(", name=").append(name).append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,13 @@
|
|||||||
package org.baeldung.persistence.multiple.model.user;
|
package org.baeldung.persistence.multiple.model.user;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -22,6 +25,9 @@ public class User {
|
|||||||
|
|
||||||
private int age;
|
private int age;
|
||||||
|
|
||||||
|
@OneToMany
|
||||||
|
List<Possession> possessionList;
|
||||||
|
|
||||||
public User() {
|
public User() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -58,6 +64,14 @@ public class User {
|
|||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Possession> getPossessionList() {
|
||||||
|
return possessionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPossessionList(List<Possession> possessionList) {
|
||||||
|
this.possessionList = possessionList;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
package org.baeldung.persistence.service;
|
package org.baeldung.persistence.service;
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.baeldung.config.ProductConfig;
|
import org.baeldung.config.ProductConfig;
|
||||||
import org.baeldung.config.UserConfig;
|
import org.baeldung.config.UserConfig;
|
||||||
import org.baeldung.persistence.multiple.dao.product.ProductRepository;
|
import org.baeldung.persistence.multiple.dao.product.ProductRepository;
|
||||||
|
import org.baeldung.persistence.multiple.dao.user.PossessionRepository;
|
||||||
import org.baeldung.persistence.multiple.dao.user.UserRepository;
|
import org.baeldung.persistence.multiple.dao.user.UserRepository;
|
||||||
import org.baeldung.persistence.multiple.model.product.Product;
|
import org.baeldung.persistence.multiple.model.product.Product;
|
||||||
|
import org.baeldung.persistence.multiple.model.user.Possession;
|
||||||
import org.baeldung.persistence.multiple.model.user.User;
|
import org.baeldung.persistence.multiple.model.user.User;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -16,15 +20,20 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = { UserConfig.class, ProductConfig.class })
|
@ContextConfiguration(classes = { UserConfig.class, ProductConfig.class })
|
||||||
|
@EnableTransactionManagement
|
||||||
public class JpaMultipleDBIntegrationTest {
|
public class JpaMultipleDBIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PossessionRepository possessionRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ProductRepository productRepository;
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
@ -37,9 +46,14 @@ public class JpaMultipleDBIntegrationTest {
|
|||||||
user.setName("John");
|
user.setName("John");
|
||||||
user.setEmail("john@test.com");
|
user.setEmail("john@test.com");
|
||||||
user.setAge(20);
|
user.setAge(20);
|
||||||
|
Possession p = new Possession("sample");
|
||||||
|
p = possessionRepository.save(p);
|
||||||
|
user.setPossessionList(Arrays.asList(p));
|
||||||
user = userRepository.save(user);
|
user = userRepository.save(user);
|
||||||
|
final User result = userRepository.findOne(user.getId());
|
||||||
assertNotNull(userRepository.findOne(user.getId()));
|
assertNotNull(result);
|
||||||
|
System.out.println(result.getPossessionList());
|
||||||
|
assertTrue(result.getPossessionList().size() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
13
spring-mvc-web-vs-initializer/.gitignore
vendored
Normal file
13
spring-mvc-web-vs-initializer/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
*.class
|
||||||
|
|
||||||
|
#folders#
|
||||||
|
/target
|
||||||
|
/neoDb*
|
||||||
|
/data
|
||||||
|
/src/main/webapp/WEB-INF/classes
|
||||||
|
*/META-INF/*
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
201
spring-mvc-web-vs-initializer/pom.xml
Normal file
201
spring-mvc-web-vs-initializer/pom.xml
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spring-mvc-web-vs-initializer</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>spring-mvc-web-vs-initializer</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.3.6.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- web -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>jstl</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- logging -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<!-- <scope>runtime</scope> -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
|
<!-- <scope>runtime</scope> --> <!-- some spring dependencies need to compile against jcl -->
|
||||||
|
</dependency>
|
||||||
|
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>log4j-over-slf4j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.5.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-library</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easymock</groupId>
|
||||||
|
<artifactId>easymock</artifactId>
|
||||||
|
<version>3.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-framework-bom</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>spring-mvc-web-vs-initializer</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- Spring -->
|
||||||
|
<org.springframework.version>4.3.1.RELEASE</org.springframework.version>
|
||||||
|
<org.springframework.security.version>4.0.4.RELEASE</org.springframework.security.version>
|
||||||
|
<javassist.version>3.20.0-GA</javassist.version>
|
||||||
|
<jstl.version>1.2</jstl.version>
|
||||||
|
|
||||||
|
<!-- persistence -->
|
||||||
|
<hibernate.version>4.3.11.Final</hibernate.version>
|
||||||
|
<mysql-connector-java.version>5.1.38</mysql-connector-java.version>
|
||||||
|
|
||||||
|
<!-- logging -->
|
||||||
|
<org.slf4j.version>1.7.13</org.slf4j.version>
|
||||||
|
<logback.version>1.1.3</logback.version>
|
||||||
|
|
||||||
|
<!-- various -->
|
||||||
|
<hibernate-validator.version>5.2.2.Final</hibernate-validator.version>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
|
<guava.version>19.0</guava.version>
|
||||||
|
<commons-lang3.version>3.4</commons-lang3.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<mockito.version>1.10.19</mockito.version>
|
||||||
|
|
||||||
|
<httpcore.version>4.4.1</httpcore.version>
|
||||||
|
<httpclient.version>4.5</httpclient.version>
|
||||||
|
|
||||||
|
<rest-assured.version>2.9.0</rest-assured.version>
|
||||||
|
|
||||||
|
<!-- maven plugins -->
|
||||||
|
<maven-compiler-plugin.version>3.5.1</maven-compiler-plugin.version>
|
||||||
|
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
<maven-resources-plugin.version>2.7</maven-resources-plugin.version>
|
||||||
|
<cargo-maven2-plugin.version>1.4.18</cargo-maven2-plugin.version>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.baeldung.config;
|
||||||
|
|
||||||
|
import org.springframework.web.WebApplicationInitializer;
|
||||||
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRegistration;
|
||||||
|
|
||||||
|
public class AppInitializer implements WebApplicationInitializer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartup(ServletContext container) throws ServletException {
|
||||||
|
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||||
|
context.setConfigLocation("org.baeldung.config");
|
||||||
|
|
||||||
|
container.addListener(new ContextLoaderListener(context));
|
||||||
|
|
||||||
|
ServletRegistration.Dynamic dispatcher = container.addServlet("java-servlet", new DispatcherServlet(context));
|
||||||
|
dispatcher.setLoadOnStartup(1);
|
||||||
|
dispatcher.addMapping("/java-servlet/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.baeldung.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
@ComponentScan(basePackages = "org.baeldung.controller.java")
|
||||||
|
public class MvcConfig extends WebMvcConfigurerAdapter {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ViewResolver viewResolver() {
|
||||||
|
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
||||||
|
viewResolver.setPrefix("/WEB-INF/view/");
|
||||||
|
viewResolver.setSuffix(".jsp");
|
||||||
|
|
||||||
|
return viewResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.baeldung.controller.java;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class JavaController {
|
||||||
|
|
||||||
|
@RequestMapping(value = "/endpoint")
|
||||||
|
public ModelAndView handleRequestFromJavaConfiguredServlet() {
|
||||||
|
ModelAndView mv = new ModelAndView();
|
||||||
|
mv.setViewName("from-java");
|
||||||
|
|
||||||
|
return mv;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.baeldung.controller.xml;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class XmlController {
|
||||||
|
|
||||||
|
@RequestMapping(value = "/endpoint")
|
||||||
|
public ModelAndView handleRequestFromXmlConfiguredServlet() {
|
||||||
|
ModelAndView mv = new ModelAndView();
|
||||||
|
mv.setViewName("from-xml");
|
||||||
|
|
||||||
|
return mv;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||||
|
|
||||||
|
<context:component-scan base-package="org.baeldung.controller.xml" />
|
||||||
|
<mvc:annotation-driven />
|
||||||
|
|
||||||
|
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||||
|
<property name="prefix">
|
||||||
|
<value>/WEB-INF/view/</value>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<value>.jsp</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,7 @@
|
|||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Java</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,7 @@
|
|||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>XML</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,24 @@
|
|||||||
|
<web-app
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||||
|
version="3.0">
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>xml-servlet</servlet-name>
|
||||||
|
<servlet-class>
|
||||||
|
org.springframework.web.servlet.DispatcherServlet
|
||||||
|
</servlet-class>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
<init-param>
|
||||||
|
<param-name>contextConfigLocation</param-name>
|
||||||
|
<param-value>classpath*:mvc-configuration.xml</param-value>
|
||||||
|
</init-param>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>xml-servlet</servlet-name>
|
||||||
|
<url-pattern>/xml-servlet/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.baeldung.controller;
|
||||||
|
|
||||||
|
import org.baeldung.config.MvcConfig;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.web.AnnotationConfigWebContextLoader;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
@ContextConfiguration(loader=AnnotationConfigWebContextLoader.class, classes = MvcConfig.class)
|
||||||
|
public class JavaServletTest {
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext wac;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJavaEndpoint() throws Exception {
|
||||||
|
ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/endpoint"))
|
||||||
|
.andReturn()
|
||||||
|
.getModelAndView();
|
||||||
|
|
||||||
|
// validate view name
|
||||||
|
Assert.assertSame(mv.getViewName(), "from-java");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package org.baeldung.controller;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.web.GenericXmlWebContextLoader;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
@ContextConfiguration(loader=GenericXmlWebContextLoader.class, locations = "classpath*:mvc-configuration.xml")
|
||||||
|
public class XmlServletTest {
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebApplicationContext wac;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testXmlEndpoint() throws Exception {
|
||||||
|
ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/endpoint"))
|
||||||
|
.andReturn()
|
||||||
|
.getModelAndView();
|
||||||
|
|
||||||
|
// validate view name
|
||||||
|
Assert.assertSame(mv.getViewName(), "from-xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,10 +15,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- Spring Boot Dependencies -->
|
<!-- Spring Boot Dependencies -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
@ -75,6 +72,11 @@
|
|||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.thoughtworks.xstream</groupId>
|
<groupId>com.thoughtworks.xstream</groupId>
|
||||||
<artifactId>xstream</artifactId>
|
<artifactId>xstream</artifactId>
|
||||||
@ -146,11 +148,19 @@
|
|||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-test</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jayway.restassured</groupId>
|
||||||
|
<artifactId>rest-assured</artifactId>
|
||||||
|
<version>${rest-assured.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.protobuf</groupId>
|
<groupId>com.google.protobuf</groupId>
|
||||||
<artifactId>protobuf-java</artifactId>
|
<artifactId>protobuf-java</artifactId>
|
||||||
<version>2.6.1</version>
|
<version>2.6.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.esotericsoftware</groupId>
|
<groupId>com.esotericsoftware</groupId>
|
||||||
<artifactId>kryo</artifactId>
|
<artifactId>kryo</artifactId>
|
||||||
@ -231,10 +241,6 @@
|
|||||||
<hibernate.version>4.3.11.Final</hibernate.version>
|
<hibernate.version>4.3.11.Final</hibernate.version>
|
||||||
<mysql-connector-java.version>5.1.39</mysql-connector-java.version>
|
<mysql-connector-java.version>5.1.39</mysql-connector-java.version>
|
||||||
|
|
||||||
<!-- marshalling -->
|
|
||||||
|
|
||||||
<jackson.version>2.7.2</jackson.version>
|
|
||||||
|
|
||||||
<!-- various -->
|
<!-- various -->
|
||||||
<hibernate-validator.version>5.2.2.Final</hibernate-validator.version>
|
<hibernate-validator.version>5.2.2.Final</hibernate-validator.version>
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@ import org.springframework.oxm.xstream.XStreamMarshaller;
|
|||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Please note that main web configuration is in src/main/webapp/WEB-INF/api-servlet.xml
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebMvc
|
@EnableWebMvc
|
||||||
@ComponentScan({ "org.baeldung.web" })
|
@ComponentScan({ "org.baeldung.web" })
|
||||||
|
@ -35,7 +35,6 @@ public class FooController {
|
|||||||
@ResponseStatus(HttpStatus.OK)
|
@ResponseStatus(HttpStatus.OK)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Foo updateFoo(@PathVariable("id") final String id, @RequestBody final Foo foo) {
|
public Foo updateFoo(@PathVariable("id") final String id, @RequestBody final Foo foo) {
|
||||||
System.out.println(foo);
|
|
||||||
return foo;
|
return foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
|
|
||||||
<context:component-scan base-package="org.baeldung.web" />
|
<context:component-scan base-package="org.baeldung.web" />
|
||||||
|
|
||||||
<mvc:annotation-driven />
|
<mvc:annotation-driven>
|
||||||
|
<mvc:message-converters register-defaults="true">
|
||||||
|
<bean class="org.baeldung.config.converter.KryoHttpMessageConverter"/>
|
||||||
|
<bean class="org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter"/>
|
||||||
|
</mvc:message-converters>
|
||||||
|
</mvc:annotation-driven>
|
||||||
|
|
||||||
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
|
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
|
||||||
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
|
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<display-name>Spring MVC Application</display-name>
|
<display-name>Spring MVC Application</display-name>
|
||||||
|
|
||||||
<!-- Spring root -->
|
<!-- Spring root -->
|
||||||
<context-param>
|
<context-param>
|
||||||
<param-name>contextClass</param-name>
|
<param-name>contextClass</param-name>
|
||||||
<param-value>
|
<param-value>
|
||||||
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package org.baeldung.web.test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.jayway.restassured.RestAssured;
|
||||||
|
|
||||||
|
public class RequestMappingLiveTest {
|
||||||
|
private static String BASE_URI = "http://localhost:8080/spring-rest/ex/";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimplePath_whenGetFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "foos").then().assertThat().body(equalTo("Simple Get some Foos"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPostFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").post(BASE_URI + "foos").then().assertThat().body(equalTo("Post some Foos"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOneHeader_whenGetFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").header("key", "val").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultipleHeaders_whenGetFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").headers("key1", "val1", "key2", "val2").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAcceptHeader_whenGetFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("application/json").get(BASE_URI + "foos").then().assertThat().body(equalTo("Get some Foos with Header New"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPathVariable_whenGetFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "foos/1").then().assertThat().body(equalTo("Get a specific Foo with id=1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMultiplePathVariable_whenGetFoos_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "foos/1/bar/2").then().assertThat().body(equalTo("Get a specific Bar with id=2 from a Foo with id=1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPathVariable_whenGetBars_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "bars/1").then().assertThat().body(equalTo("Get a specific Bar with id=1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenParams_whenGetBars_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "bars?id=100&second=something").then().assertThat().body(equalTo("Get a specific Bar with id=100"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetFoosOrBars_thenOk() {
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "advanced/foos").then().assertThat().body(equalTo("Advanced - Get some Foos or Bars"));
|
||||||
|
RestAssured.given().accept("text/html").get(BASE_URI + "advanced/bars").then().assertThat().body(equalTo("Advanced - Get some Foos or Bars"));
|
||||||
|
}
|
||||||
|
}
|
@ -3,9 +3,7 @@ package org.baeldung.web.test;
|
|||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.baeldung.config.converter.KryoHttpMessageConverter;
|
import org.baeldung.config.converter.KryoHttpMessageConverter;
|
||||||
import org.baeldung.web.dto.Foo;
|
import org.baeldung.web.dto.Foo;
|
||||||
@ -17,11 +15,7 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
|
||||||
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||||
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
|
|
||||||
import org.springframework.oxm.xstream.XStreamMarshaller;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,7 +44,6 @@ public class SpringHttpMessageConvertersIntegrationTestsCase {
|
|||||||
final String URI = BASE_URI + "foos/{id}";
|
final String URI = BASE_URI + "foos/{id}";
|
||||||
|
|
||||||
final RestTemplate restTemplate = new RestTemplate();
|
final RestTemplate restTemplate = new RestTemplate();
|
||||||
restTemplate.setMessageConverters(getMessageConverters());
|
|
||||||
|
|
||||||
final HttpHeaders headers = new HttpHeaders();
|
final HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
|
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
|
||||||
@ -67,7 +60,6 @@ public class SpringHttpMessageConvertersIntegrationTestsCase {
|
|||||||
final String URI = BASE_URI + "foos/{id}";
|
final String URI = BASE_URI + "foos/{id}";
|
||||||
|
|
||||||
final RestTemplate restTemplate = new RestTemplate();
|
final RestTemplate restTemplate = new RestTemplate();
|
||||||
restTemplate.setMessageConverters(getMessageConverters());
|
|
||||||
|
|
||||||
final HttpHeaders headers = new HttpHeaders();
|
final HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
|
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
|
||||||
@ -83,7 +75,6 @@ public class SpringHttpMessageConvertersIntegrationTestsCase {
|
|||||||
public void givenConsumingXml_whenWritingTheFoo_thenCorrect() {
|
public void givenConsumingXml_whenWritingTheFoo_thenCorrect() {
|
||||||
final String URI = BASE_URI + "foos/{id}";
|
final String URI = BASE_URI + "foos/{id}";
|
||||||
final RestTemplate restTemplate = new RestTemplate();
|
final RestTemplate restTemplate = new RestTemplate();
|
||||||
restTemplate.setMessageConverters(getMessageConverters());
|
|
||||||
|
|
||||||
final Foo resource = new Foo(4, "jason");
|
final Foo resource = new Foo(4, "jason");
|
||||||
final HttpHeaders headers = new HttpHeaders();
|
final HttpHeaders headers = new HttpHeaders();
|
||||||
@ -129,20 +120,4 @@ public class SpringHttpMessageConvertersIntegrationTestsCase {
|
|||||||
assertThat(resource, notNullValue());
|
assertThat(resource, notNullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTIL
|
|
||||||
|
|
||||||
private List<HttpMessageConverter<?>> getMessageConverters() {
|
|
||||||
final List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
|
||||||
|
|
||||||
final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
|
|
||||||
final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
|
|
||||||
xmlConverter.setMarshaller(xstreamMarshaller);
|
|
||||||
xmlConverter.setUnmarshaller(xstreamMarshaller);
|
|
||||||
|
|
||||||
converters.add(xmlConverter);
|
|
||||||
converters.add(new MappingJackson2HttpMessageConverter());
|
|
||||||
|
|
||||||
return converters;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.baeldung.spring;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.springframework.web.WebApplicationInitializer;
|
||||||
|
import org.springframework.web.context.request.RequestContextListener;
|
||||||
|
|
||||||
|
public class ListenerConfig implements WebApplicationInitializer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartup(ServletContext sc) throws ServletException {
|
||||||
|
// Manages the lifecycle of the root application context
|
||||||
|
sc.addListener(new RequestContextListener());
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package org.baeldung.spring;
|
package org.baeldung.spring;
|
||||||
|
|
||||||
import org.baeldung.web.interceptor.LoggerInterceptor;
|
import org.baeldung.web.interceptor.LoggerInterceptor;
|
||||||
|
import org.baeldung.web.interceptor.SessionTimerInterceptor;
|
||||||
import org.baeldung.web.interceptor.UserInterceptor;
|
import org.baeldung.web.interceptor.UserInterceptor;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
@ -15,7 +16,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan("org.baeldung.web")
|
@ComponentScan("org.baeldung.web")
|
||||||
@EnableWebMvc
|
@EnableWebMvc
|
||||||
public class WebConfig extends WebMvcConfigurerAdapter {
|
public class WebConfig extends WebMvcConfigurerAdapter{
|
||||||
|
|
||||||
public WebConfig() {
|
public WebConfig() {
|
||||||
super();
|
super();
|
||||||
@ -42,5 +43,7 @@ public class WebConfig extends WebMvcConfigurerAdapter {
|
|||||||
public void addInterceptors(final InterceptorRegistry registry) {
|
public void addInterceptors(final InterceptorRegistry registry) {
|
||||||
registry.addInterceptor(new LoggerInterceptor());
|
registry.addInterceptor(new LoggerInterceptor());
|
||||||
registry.addInterceptor(new UserInterceptor());
|
registry.addInterceptor(new UserInterceptor());
|
||||||
|
registry.addInterceptor(new SessionTimerInterceptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package org.baeldung.web.interceptor;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||||
|
|
||||||
|
public class SessionTimerInterceptor extends HandlerInterceptorAdapter {
|
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(SessionTimerInterceptor.class);
|
||||||
|
|
||||||
|
private static final long MAX_INACTIVE_SESSION_TIME = 5 * 10000;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpSession session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed before actual handler is executed
|
||||||
|
**/
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
|
||||||
|
throws Exception {
|
||||||
|
log.info("Pre handle method - check handling start time");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
request.setAttribute("executionTime", startTime);
|
||||||
|
if (UserInterceptor.isUserLogged()) {
|
||||||
|
session = request.getSession();
|
||||||
|
log.info("Who is logged in: " + SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
log.info("Time since last request in this session: "
|
||||||
|
+ (System.currentTimeMillis() - request.getSession().getLastAccessedTime()) + " ms");
|
||||||
|
if (System.currentTimeMillis() - session.getLastAccessedTime() > MAX_INACTIVE_SESSION_TIME) {
|
||||||
|
log.warn("Logging out, due to inactive session");
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
request.logout();
|
||||||
|
response.sendRedirect("/spring-security-rest-full/logout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed before after handler is executed
|
||||||
|
**/
|
||||||
|
@Override
|
||||||
|
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler,
|
||||||
|
final ModelAndView model) throws Exception {
|
||||||
|
log.info("Post handle method - check execution time of handling");
|
||||||
|
long startTime = (Long) request.getAttribute("executionTime");
|
||||||
|
log.info("Execution time for handling the request was: " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package org.baeldung.web.interceptor;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.baeldung.spring.PersistenceConfig;
|
||||||
|
import org.baeldung.spring.SecurityWithoutCsrfConfig;
|
||||||
|
import org.baeldung.spring.WebConfig;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@WebAppConfiguration
|
||||||
|
@Transactional
|
||||||
|
@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class })
|
||||||
|
@WithMockUser(username = "admin", roles = { "USER", "ADMIN" })
|
||||||
|
public class SessionTimerInterceptorTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WebApplicationContext wac;
|
||||||
|
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After execution of HTTP GET logs from interceptor will be displayed in
|
||||||
|
* the console
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testInterceptors() throws Exception {
|
||||||
|
HttpSession session = mockMvc.perform(get("/auth/admin")).andExpect(status().is2xxSuccessful()).andReturn()
|
||||||
|
.getRequest().getSession();
|
||||||
|
Thread.sleep(51000);
|
||||||
|
mockMvc.perform(get("/auth/admin").session((MockHttpSession) session)).andExpect(status().is2xxSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user