Get Custom Property Of User Principal - spring-security

I have a custom user details object with first name part of it. Below username works, but I want something like the second to work. How can I access this custom property?
<security:authentication property="principal.username" />
<security:authentication property="principal.firstname" />

I presume that you tried the above and that it didn't work.
Check your custom user details class to make sure that the capitalization of the getter and setter methods for the 'firstname' property are correct.

Works for me. Here's my test code:-
CustomUserDetails class
public class CustomUserDetails implements UserDetails {
public String getFirstName() {
return "hello";
}
...
}
Custom tag in JSP
The following tag returns hello.
<security:authentication property="principal.firstName" />
By the way, make sure you are not putting getFirstName() into the anonymous class, because that will not work.
What I'm trying to say here is, don't do this:-
...
return new UserDetails() {
// adding extra method here will not work
public String getFirstName() {
return "hello";
}
public String getUsername() {
return "test";
}
...
};
... do this:-
...
// this class implements UserDetails and contains getFirstName()
CustomUserDetails csd = new CustomUserDetails();
csd.set...(...)
...
return csd;

Related

Struts 2.5.12: Text tag displays name of the field from model class instead of value

I am uppgrading one of the project from Struts 2.3.3 to 2.5.12 and I see that in the upgraded project <s:text /> tag is unable to display the value of the field from model class and instead it just displays the name. It works perfectly fine when I use Struts 2.3.3.
My Action class is like:
public class MyAction {
private Member member;
public Member getMember() {
return member;
}
}
My model classes are like:
public class Member implements Serializable {
private Address address;
public Address getAddress() {
return address;
}
}
public class Address implements Serializable {
private String city;
public String getCity() {
return city;
}
}
In the JSP, I have:
<s:text name="member.address.city" />
The output I see on page is member.address.city, where as I am expecting the value of the city.
I see in debug mode that control is coming to the getCity() method of Address class and the city field has the value London, but still it doesn't get displayed in UI.
Does anyone know what the issue is?
According to the docs:
If the named message is not found in a property file, then the body of
the tag will be used as default message. If no body is used, then the
stack can be searched, and if a value is returned, it will written to
the output. If no value is found on the stack, the key of the message
will be written out.

Search method in Struts with MySQL

Hey guys I'm having some problems with a project that I'm doing :/
I have this code
public class ListaAlumnoAction {
private List<Alumno> alumnos;
public String execute(){
String camino="success";
EntityManager em= Utilitario.getInstance().getEntityManager();
Query query=em.createQuery("Select o From Alumno o");
alumnos=query.getResultList();
return camino;
}
public List<Alumno> getAlumnos() {
return alumnos;
}
public void setAlumnos(List<Alumno> alumnos) {
this.alumnos = alumnos;
}
}
This method gives me a list of students. But in this case I just want 1 student, searching by code for example or by name and last name. The thing is I don't know what kind of tools use for this purpose.
Thanks in advanced.
For searching the student by specified input criteria, you are in need of passing the required input from the page to the action class. And need to modify the query which will search the student record by mentioned name or last name or desired input.
For example, assume student name is the input criteria
To pass the student name from the page:
<s:form>
......
<s:textfield name="studentName" label="Student Name"></s:textfield>
<s:submit value="Search" name="submit" action="ListaAlumnoAction"/>
......
</s:form>
Here the studentName will be the input for search operation and ListaAlumnoAction is action which will fired when Search button clicked.
To get the Student Name in the Action Class:
public class ListaAlumnoAction {
private List<Alumno> alumnos;
/* Please note both the text filed name in the page and attribute should be same "studentName" */
private String studentName;
public String execute(){
String camino="success";
EntityManager em= Utilitario.getInstance().getEntityManager();
// "name" variable will hold the studentName
String name = getStudentName();
// Modify the query, by passing the name if it is not null
Query query=em.createQuery("Select o From Alumno o");
alumnos=query.getResultList();
return camino;
}
public List<Alumno> getAlumnos() {
return alumnos;
}
public void setAlumnos(List<Alumno> alumnos) {
this.alumnos = alumnos;
}
// getter and setter for the studentName
public String getStudentName(){
return studentName;
}
public void setStudentName(String studentName){
this.studentName = studentName;
}
}

JSF view parameter fails when accessing method defined with generics

I have uncovered some strange behavior trying to set a value with a view parameter. The code below does NOT work...upon submission of the form with the view parameter, the id value is NOT set. However, if the comments are removed from the getId and setId methods, the id value IS properly set. Is there some issue with JSF EL when accessing generics, or am I doing something terribly wrong? Can anyone explain this behavior?
Interestingly, I receive no exceptions...the value is simply not set. In fact, the setId method in the abstract class is not even called.
public abstract class AbstractBusinessObjectAction<E, ID extends Serializable> {
protected abstract BusinessObjectManager<E, ID> getBusinessObjectManager();
public ID getId() {
ID id = getBusinessObjectManager().getId();
return id;
}
public void setId(final ID id) {
getBusinessObjectManager().setId(id);
}
}
#Named("configuration")
#ConversationScoped
public class ConfigurationAction extends AbstractBusinessObjectAction<ConfigurationParameter, Long> {
#Inject
private ConfigurationParameterManager manager;
protected BusinessObjectManager<ConfigurationParameter, Long> getBusinessObjectManager() {
return manager;
}
// public Long getId() {
// Long id = super.getId();
// return id;
// }
// public void setId(Long id) {
// super.setId(id);
// }
}
Following is an except from the .xhtml:
<f:metadata>
<f:viewParam id="entityIdParam" name="entityId" value="#{configuration.id}" />
</f:metadata>
Adding a converter solved the problem.
<f:viewParam id="entityIdParam" name="entityId" value="#{configuration.id}" >
<f:converter converterId="javax.faces.Long" />
</f:viewParam>
To the best of my knowledge, this is the reason:
Because the id property is of type ID extends Serializable in the abstract class, JSF tries to install a non-existant Serializable converter. The reason the code works when I uncomment the methods indicated, is that JSF properly detects that it needs a javax.faces.Long converter based on the explicit declaration of Long on the property methods for the "id" property.
Thanks to #Damian for the tip!

Changing null strings to string.Empty using ValueInjecter

I'm using ValueInjecter to flatten/unflatten view models into domain objects created by Entity Framework (4.3.1) model-first. All of my VARCHAR columns in my database are NOT NULL DEFAULT '' (personal preference, no desire to open up a holy war here). On post, the view model comes back with any string property that has no value as null, so when I attempt to inject it back into my domain model class, EF barks at me for attempting to set a property with IsNullable=false to null. Example (over-simple):
public class ThingViewModel
{
public int ThingId{get;set;}
public string Name{get;set;}
}
public class Thing
{
public global::System.Int32 ThingId
{
//omitted for brevity
}
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.String Name
{
//omitted for brevity
}
}
Then, my controller post looks like this:
[HttpPost]
public ActionResult Edit(ThingViewModel thing)
{
var dbThing = _thingRepo.GetThing(thing.ThingId);
//if thing.Name is null, this bombs
dbThing.InjectFrom<UnflatLoopValueInjection>(thing);
_thingRepo.Save();
return View(thing);
}
I'm using UnflatLoopValueInjection because I have nested types in the actual domain version of Thing. I attempted to write a custom ConventionInjection to convert null strings to string.Empty, but it appears that UnflatLoopValueInjection switches it back to null. Is there a way I can get ValueInjecter not to do this?
Nuts, I just figured it out with help from the wiki. The solution appears to be to extend UnflatLoopValueInjection:
public class NullStringUnflatLoopValueInjection : UnflatLoopValueInjection<string, string>
{
protected override string SetValue(string sourceValue)
{
return sourceValue ?? string.Empty;
}
}

Building action parameter object from XHR-request data MVC3

I have this action in my RESTful application on MVC3:
[HttpPut]
public void Rest(ViewModel view_model, int id)
{
//doing something with view_model
}
Where ViewModel class is a class for passing data to/from client Javascript (I don`t want to pass pure DB entities):
public class ViewModel
{
public ViewModel() //parameterless constructor, needed for accepting as parameter in action
{
}
public ViewModel(Model m)
{
id = m.ID;
Title = m.Title;
}
public int? id { get; set; }
private string _title;
public string Title
{
get
{
if (String.IsNullOrWhiteSpace(_title)) throw new Exception("Empty field");
return _title;
}
set
{
_title = value;
}
}
}
BUT when I make PUT request with that data:
{ "id" : 7, "Title" : "Hello world!" }
I get that "Empty field" exception. Seems like something is trying to get Title property, even before it has been set with incoming "Hello world!" data.
Why?
And where can I get some information, how this whole operation works, i.e. looking for object ViewModel that specified as action parameter, in actual XHR-request.
Thank you for your thoughts.
Seems like something is trying to get Title property, even before it
has been set with incoming "Hello world!" data. Why?
It is the default model binder. And more specifically the BindProperty method. This method is called during binding and it uses reflection to call the getter. Because the model binder recurses down the object hierarchy graph it first needs to get the value of the property, build a binding context and model metadata for each property and then invoke the SetProperty method.
If you don't want the title property to be empty use the validation mechanisms and auto implemented properties:
[Required]
public string Title { get; set; }
and then in your RESTful action check if the ModelState.IsValid. It is much more easier and MVCish:
[HttpPut]
public ActionResult Rest(ViewModel view_model, int id)
{
if (!ModelState.IsValid)
{
...
}
// doing something with view_model
...
}

Resources