Why is this BeanPostProcessor needed in addition to a UserDetailsService in this Spring 3.0 authentication example? - authentication

I'm trying to understand a Spring 3.0 application which contains the following BeanPostProcessor implementation. What is this code needed for? I thought the UserDetailsService was sufficient for getting and setting the User account information.
#Service
public class UserPassAuthFilterBeanPostProcessor implements BeanPostProcessor
{
/**
* The username parameter.
*/
private String usernameParameter;
/**
* The password parameter.
*/
private String passwordParameter;
#Override
public final Object postProcessAfterInitialization(final Object bean, final String beanName)
{
return bean;
}
#Override
public final Object postProcessBeforeInitialization(final Object bean, final String beanName)
{
if (bean instanceof UsernamePasswordAuthenticationFilter)
{
final UsernamePasswordAuthenticationFilter filter = (UsernamePasswordAuthenticationFilter) bean;
filter.setUsernameParameter(getUsernameParameter());
filter.setPasswordParameter(getPasswordParameter());
}
return bean;
}
/**
* Sets the username parameter.
*
* #param usernameParameter
* the username parameter
*/
public final void setUsernameParameter(final String usernameParameter)
{
this.usernameParameter = usernameParameter;
}
/**
* Gets the username parameter.
*
* #return the username parameter
*/
public final String getUsernameParameter()
{
return usernameParameter;
}
/**
* Sets the password parameter.
*
* #param passwordParameter
* the password parameter
*/
public final void setPasswordParameter(final String passwordParameter)
{
this.passwordParameter = passwordParameter;
}
/**
* Gets the password parameter.
*
* #return the password parameter
*/
public final String getPasswordParameter()
{
return passwordParameter;
}
}

Yes, UserDetailsService is sufficient.
This BeanPostProcessor changes the names of username and password parameters in login request (i.e. names of fields in login form) - these properties can't be configured via namespace configuration, and using BeanPostProcessorss in order to customize such properties is an ugly but quite common practice.

This postProcessBeforeInitialization() method is implemented from BeanPostProcessor interface which automatically executes after your getter and setter methods finish executing
and once the postProcessBeforeInitialization() method finish execution, objects are initialized and then postProcessAfterInitialization() will execute.
These are something like life cycle methods.

Related

How to construct addToFront method

I have a IUArrayList class which implements IndexedUnsortedList interface and I have some constructors written but I need help writing the addToFront method. I have the addToRear method written and some other constructors done but I'm not sure about how to do addToFront. If you need to see more code let me know but this arraylist also uses an iterator which I keep track of with the modCount variable.
public class IUArrayList<T> implements IndexedUnsortedList<T> {
private static final int DEFAULT_CAPACITY = 10;
private static final int NOT_FOUND = -1;
private T[] array;
private int rear;
private int modCount;
/** Creates an empty list with default initial capacity */
public IUArrayList() {
this(DEFAULT_CAPACITY);
}
/**
* Creates an empty list with the given initial capacity
* #param initialCapacity
*/
#SuppressWarnings("unchecked")
public IUArrayList(int initialCapacity) {
array = (T[])(new Object[initialCapacity]);
rear = 0;
modCount = 0;
}
/** Double the capacity of array */
private void expandCapacity() {
array = Arrays.copyOf(array, array.length*2);
}
#Override
public void addToFront(T element) {
// TODO
}
#Override
public void addToRear(T element) {
expandCapacity();
array[rear] = element;
rear++;
modCount++;
}
Below is the Interface that it implements.
public interface IndexedUnsortedList<T> extends Iterable<T>
{
/**
* Adds the specified element to the front of this list.
*
* #param element the element to be added to the front of this list
*/
public void addToFront(T element);
/**
* Adds the specified element to the rear of this list.
*
* #param element the element to be added to the rear of this list
*/
public void addToRear(T element);
If you use LinkedList instead of Array. You would be able to utilize addFirst and addLast methods of LinkedList to achieve what you want to achieve.

How to put a path param to the request body before validation happens?

I got the following test entity:
public class Test {
public String id;
public String name;
}
My test resource looks like this:
#Path("test")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class TestResource {
#Path("{id}")
#POST
public Test test(#Valid Test test){
return test;
}
}
If I do a POST with name as request body, I will end up with an entity which has a name but no id set. If I want to have set the id, I define a #PathParam("id") String id and then set the id with test.id = id. That is what I am using right now.
In this case, if I put a #NotNull constraint to the ID, the validation fails.
How can I 'put' the parsed ID to the request body, before the validation is happening? Ideal, not manually in any case.
You should remove the #NotNull annotation and ensure that no ID is given from the POST request. And in your GET endpoints ensure that the field is not null, probably with an own annotation. I did this with my own annotation #TestIdNull(false).
In your code you would place the annotation like this:
#Path("{id}")
#POST
public Test test(#TestIdNull(true) Test test){
return test;
}
while the annotation interface looks quite simple:
#Target({ElementType.PARAMETER,ElementType.TYPE_USE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Constraint(validatedBy = PetIdNullValidator.class)
public #interface TestIdNull {
String message() default "Post request. ID value forbidden.";
boolean value() default true;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
and the implementation would be
#Provider
#NoArgsConstructor
public class TestIdNullValidator implements ConstraintValidator<TestIdNull, Test> {
private boolean switchNullCheck;
/**
* {#inheritDoc}
*/
#Override
public void initialize(final TestIdNull constraintAnnotation) {
switchNullCheck = constraintAnnotation.value();
}
/**
* {#inheritDoc}
*/
#Override
public boolean isValid(final Test test, final ConstraintValidatorContext context) {
if (null == test) {
return true;
}
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("ENTER YOUR MESSAGE HERE").addConstraintViolation();
return switchNullCheck ? test.id() == null : test.id() != null;
}
}
On your "way back" (the GET methods) you must ensure the ID is not null with placing the annotation to your DTO. Code could look like this:
#TestIdNull(false)
final Test test = mapper.map(entity, Test.class);
I know it's not a very elegant way but your idea placing the ID in a POST first and then validate is not possible I'm afraid.

Manually convert JSON to Object using Spring Data Rest

Let's say I have the following entity:
public class Employee {
private String name;
private Company company
}
And I have a String with the content below:
{
"name":"Joe",
"company": "http://localhost/companies/23"
}
Spring Data Rest is capable of converting this JSON to an Employee object out of the box, but to how convert it manually?
OK. I think I understand the problem now. Of course SDR has to have an ObjectMapper which is capable to convert the incoming JSON into an entity (including hateoas links), but it seems that's NOT the default ObjectMapper and it's not even exported as a Bean.
So I made some reverse-engineering and I think I've found what you need. Fortunately the ObjectMapper which is used internally has a public getter in the RepositoryRestMvcConfiguration class, so it can be used easily:
/**
* The Jackson {#link ObjectMapper} used internally.
*
* #return
*/
public ObjectMapper objectMapper() {
return mapper.get();
}
I think the following code will work:
#Autowired
RepositoryRestMvcConfiguration rrmc;
private <T> T readValue(String json, Class<T> type)
throws IOException, JsonParseException, JsonMappingException {
return rrmc.objectMapper().readValue(json, type);
}
#Aurowired
private final RepositoryInvokerFactory repositoryInvokerFactory;
private Object loadPropertyValue(Class<?> type, String href) {
String id = href.substring(href.lastIndexOf('/') + 1);
RepositoryInvoker invoker = repositoryInvokerFactory.getInvokerFor(type);
return invoker.invokeFindById(id).orElse(null);
}

When I use a function that I append to the class Controller, it does not work in Yii

I appended a xxx function to the class Controller, then I touched a file named 'VideoController'. It's extends Controller.
When I execute the VideoController, the xxx function can't be called, why?
the function ajaxReturn :
class Controller extends CController
{
/**
* #var string the default layout for the controller view. Defaults to '//layouts/column1',
* meaning using a single column layout. See 'protected/views/layouts/column1.php'.
*/
public $layout='//layouts/column1';
/**
* #var array context menu items. This property will be assigned to {#link CMenu::items}.
*/
public $menu=array();
/**
* #var array the breadcrumbs of the current page. The value of this property will
* be assigned to {#link CBreadcrumbs::links}. Please refer to {#link CBreadcrumbs::links}
* for more details on how to specify this property.
*/
public $breadcrumbs=array();
/**
* zhoumengkang
* 从Thinkphp里拖过来的
*/
protected function ajaxReturn($data,$info='',$status=1,$type='JSON') {
$result = array();
$result['status'] = $status;
$result['info'] = $info;
$result['data'] = $data;
if(strtoupper($type)=='JSON') {
header("Content-Type:text/html; charset=utf-8");
exit(json_encode($result));
}elseif(strtoupper($type)=='XML'){
header("Content-Type:text/xml; charset=utf-8");
exit(xml_encode($result));
}elseif(strtoupper($type)=='EVAL'){
header("Content-Type:text/html; charset=utf-8");
exit($data);
}else{
// TODO
}
}
}
but it can't by called in
class VideoController extends Controller {
public function actionTest() {
$this->ajaxReturn(true,'test',1);
}
}
You have to import your controller before extend.
Yii::import('application.controllers.Controller');
class VideoController extends Controller {
public function actionTest() {
$this->ajaxReturn(true,'test',1);
}
}
Better change your controller name from Controller to someothername.

how to implement Queue in javaBeans

I have an instance of NotificationEvent. i have added this instance in a queue whenever this instance is created.Name of the queue should be NotificationQueue.
structure of NotificationEvent is like this :
public class NotificationEvent {
private String sender;
private String receiver;
private String message;
/**
* #return the sender
*/
public String getSender() {
return sender;
}
/**
* #param sender the sender to set
*/
public void setSender(String sender) {
this.sender = sender;
}
/**
* #return the receiver
*/
public String getReceiver() {
return receiver;
}
/**
* #param receiver the receiver to set
*/
public void setReceiver(String receiver) {
this.receiver = receiver;
}
/**
* #return the message
*/
public String getMessage() {
return message;
}
/**
* #param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
What should be the required structure of NotificationQueue?
I suggest to not reinvent the wheel again. The interface Queue, already in the Java run-time library, defines operations which a queue should have. Here a brief tutorial for the Queue interface and the Queue JavaDoc. Well, here also a example of using Queue implementations.
You can create a Notification queue object like this:
Queue<NotificationEvent> eventQueue = new LinkedList<NotificationEvent>;
or, if you insist on having your own type for the queue:
public class extends LinkedList<NotificationEvent> {
/**
* Constructs an empty list.
*/
public NotificationQueue() {
}
/**
* Constructs a list containing the elements of the specified collection,
* in the order they are returned by the
* collection's iterator.
* #param c the collection whose elements are to be placed into this list
* #throws NullPointerException if the specified collection is null
*/
public NotificationQueue(Collection<? extends NotificationEvent> c) {
super(c);
}
}
...
NotificationQueue eventQueue == new NotificationQueue();
Note:
LinkedList is not the only available implementation of the Queue interface, see the Queue JavaDoc for other implementations already available in the Java run-time libs. Of course, you could also write your own implementation of the Queue interface.