I often want to refine posted data before use it, for example
public class Song() {
public String[] tags;
public String csvTags;
public void setTagsWithCsv() {
// this one should be more complicated for handling real data
this.tags = csvTags.split(",");
}
}
In this case, I have to call setTagsWithCsv method inside the method of the controller class.
#RequestMapping(value = "/song/create", method = POST)
public String createSong(Song song) {
song.setTagsWithCsv();
songService.create(song); // some code like this will come here
...
}
Is there any way to call the method with an annotation like '#PostConstruct'? The method should be called after a post request.
Maybe you just provided a bad example, but If your Song is in a form of POJO, you do it on a call to setCsvTags
public class Song {
private String[] tags;
private String csvTags;
public void setCsvTags(String csvTags) {
this.csvTags = csvTags;
this.tags = csvTags.split(",");
}
public void setTags(String[] tags) {
this.tags == tags;
String newCsvTags = Arrays.toString(tags);
this.csvTags = newCsvTags.substring(1, newCsvTags.length() - 1); // get rid of []
}
}
or make a method, without keeping explicit tags array
public class Song {
private String csvTags;
public void getTags() {
return csvTags.split(",");
}
}
Otherwise, there is no standard way of doing this, you can play with request interception before reaching your Controller, but I think it would be just a waste of time.
Related
I need to create a book library that will be a singleton. It contains a map of books. Each book has its own index number and genre (taken from enum). How can I add a method that returns a list of all books by genre (genre is transmitted as a string in different registers and I need to use a switch in the method). P.S. I am self-taught so I will be very happy if you can explain me, how can I do it.
My main question is, how can I assign a value from enum(genre) to multiple class objects(books) that I put in. a collection and output them using switch?
Here is my code:
public class Result {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton.books.put(1,new Books("The Great Gatsby.", "Alex Lomi"));
singleton.books.put(2,new Books("Don Quixote","Samuel Puga"));
singleton.books.put(3,new Books("Beloved", "Antony Gradsby"));
singleton.books.put(4,new Books("To Kill a Mockingbird","Sofia Beluci" ));
singleton.books.put(5,new Books("One Hundred Years of Solitude", "Laura Petera"));
singleton.books.put(6,new Books("One Hundred Years of Solitude", "Kristian Roberts"));
}
}
public class Singleton {
private static Singleton LIBRARY;
public Singleton() {
}
public static Singleton getInstance(){
if(LIBRARY == null){
LIBRARY = new Singleton();
}
return LIBRARY;
}
Map<Integer, Books> books = new TreeMap<>();
}
public class Books {
private String nameOfBook;
private String author;
public Books(String nameOfBook, String author) {
this.nameOfBook = nameOfBook;
this.author = author;
}
}
public enum Genre {
ACTION,
COMEDY,
DRAMA,
FANTASY;
//I've started trying, but if there will be 100 books of the same genre, it will be hard to write every book using switch method.
public static Genre getGenre(String genre){
switch (genre.toUpperCase()){
case "COMDEY":
return
}
}
}
I have searched and everything seems to say as long as you use spring 4+ I should be able to use dot notation to bind request parameters to a pojo.
This is what my request looks like:
And this is what my controller looks like:
And my dto:
I even tried adding #RequestParam("p.page") int page in the controller to make sure my endpoint was getting hit and it does. Am I missing something obvious or am I not allowed to use dot notation to populate a pojo with a spring controller?
And the parent class:
public class JhmPageableDto
{
private String query;
private int page;
private int size;
private String sort;
private boolean sortAsc;
public String getQuery()
{
return query;
}
public void setQuery(String query)
{
this.query = query;
}
public int getPage()
{
return page;
}
public void setPage(int page)
{
this.page = page;
}
public int getSize()
{
return size;
}
public void setSize(int size)
{
this.size = size;
}
public String getSort()
{
return sort;
}
public void setSort(String sort)
{
this.sort = sort;
}
public boolean isSortAsc()
{
return sortAsc;
}
public void setSortAsc(boolean sortAsc)
{
this.sortAsc = sortAsc;
}
}
I have a model Object with so many Optionals. That model object is used in whole transactions.
At the beginning of the transaction I need to put the default value in optional fields.
So
1 approach is to convert in an object with non optional values, but then I'll have a redundant class for no reason. second approach is how I did below, but is there a better way to write updateDefaults method
class SampleRequest{
Optional<String> a;
Optional<String> b;
Optional<String> c;
Optional<String> d;
}
public void doSomething(SampleRequest sampleRequest){
updateDefaults(sampleRequest)
call other services ...
}
void updateDefaults(SampleRequest sampleRequest){
String aa= sampleRequest.getA().orElse("A"); // Application specific complex logic. values has to be set
sampleRequest.setA(Optional.of(aa));
and so one....
}
What is the better way towrite updateDefaults method ?
I'd potentially use a decorator
interface Request {
Optional<String> getA();
}
class SampleRequest implements Request {
private final String a;
public Optional<String> getA() {
return Optional.ofNullable(a);
}
}
// Decorator
class DefaultingRequest implements Request {
private final Request delegate;
public Optional<String> getA() {
return Optional.of(
delegate.getA().orElse(DEFAULT_A)
);
}
}
Then any time you want the safety of the defaults, you can wrap your request.
return new DefaultingRequest(aSampleRequest);
You could alternatively introduce a new interface. The downside of this is that you can't treat Request the same as FilledRequest. The upside is that you know if the defaults have already been applied. With the above approach, you could wrap the same thing several times unneccessarily.
interface Request {
Optional<String> getA();
FilledRequest toFilledRequest();
}
class SampleRequest implements Request {
//...
public FilledRequest toFilledRequest() {
return new FilledSampleRequest(this);
}
}
interface FilledRequest { // the same as Request, but not Optional
String getA();
}
class FilledSampleRequest {
private final SampleRequest sampleRequest;
public String getA() {
return sampleRequest.orElse(DEFAULT_A);
}
}
As far as my understanding goes, method references can be used either statically or with wrapped object instance, for example:
public class MethodReferencesExampleTest {
class Example {
private String variable;
public Example(String variable) {
this.variable = variable;
}
public String getVariable() {
return variable;
}
}
#Test
public void shouldBeAbleToUseBothClassAndInstanceMethodReference() {
Example objectUnderTest = new Example("variable");
useClassMethodReference(Example::getVariable, objectUnderTest);
useInstanceMethodReference(objectUnderTest::getVariable);
}
private <T> void useClassMethodReference(Function<T, String> methodReference, T object) {
System.out.println("Class reference call result = " + methodReference.apply(object));
}
private void useInstanceMethodReference(Supplier<String> methodReference) {
System.out.println("Instance reference call result = " + methodReference.get());
}
}
What I would like to do is extract instance method reference and somehow convert it to class method reference, so that I could apply it to a different object of the same class, like:
private <T> void useInstanceMethodReferenceOnDifferentObjectThanItsSource(Supplier<String> instanceMethodReference, T object) {
Function<T, String> classMethodReference = /* some magical conversion */ instanceMethodReference;
System.out.println("Instance reference call result = " + classMethodReference.apply(object));
}
Is it at all possible? Byte-code wizardry like using cglib or even shady "hacks" are an acceptable answer.
I am not able to get the value of radio button selected in a page
I have a JSP page as
<body>
<s:form action="/YYY" id="frmPersonalPage" name="frmPersonalPage" >
<s:radio name ="radio" list="skillMasterData"></s:radio>
</s:form>
</body>
This renders properly . In my struts.xml I have
<action name="YYY" class="com.tdi.atom.actions.CCC" method="showEditSkillMasterPage">
<result name ="success">/jsp/modules/skillmap/createskillmaster.jsp</result>
</action>
In my action class I have this
public class CCC extends BaseActionSupport {
private ArrayList skillMasterData;
public String radio;
private ArrayList l1;
private ArrayList l2;
private ArrayList l3;
public ArrayList getSkillMasterData() {
return skillMasterData;
}
public void setSkillMasterData(ArrayList skillMasterData) {
this.skillMasterData = skillMasterData;
}
public String showEditSkillMasterPage()
{ log.info("at showEditSkillMasterPage");
System.out.println("radio buttoneee : "+getRadio());//this is null
setEditType("EDIT");
return SUCCESS;
}
public String showListSkillMasterPage()
{
SkillMasterDB pddb =new SkillMasterDB();
JdbcHelper helper;
l1 =new ArrayList();
l2=new ArrayList();
l3=new ArrayList();
l1.add("asda");
l1.add("rqwrq");
l2.add("!####");
l2.add("9087907");
l3.add("./,/");
l3.add("[][][]");
skdto.add(l1);
skdto.add(l2);
skdto.add(l3);
setSkillMasterData(skdto);
return SUCCESS;
}
public String getRadio() {
return radio;
}
public void setRadio(String radio) {
this.radio = radio;
}
}
In BaseActionSupport class I have
public class BaseActionSupport extends ActionSupport implements SessionAware {
private Map userSession;
public UserDTO user;
public UserDTO getUser() {
return mgr.getUser();
}
public boolean isAdmin() {
return mgr.isUserADMIN();
}
public void setSession(Map session) {
userSession = session; mgr = new SecurityManager(userSession);
}
}
I just can't figure out why such simple code is not working. Else where very similar code works fine.
There are some strange things in your code.
Assuming CCC and YYY are obfuscated names created only for posting them here (otherwise, you should use CamelCase with first letter capitalized for class names, like MyAction),
you should respect JavaBeans conventions, then userSession should become session, because the accessors methods (getters and setters) should always respect the name of the private variable);
skdto variable is not initialized nor defined in your showListSkillMasterPage method;
I'm not sure if using ArrayList<ArrayList<String>> for radio button is good. You could try with a simple ArrayList<String>, like:
public String showListSkillMasterPage() {
SkillMasterDB pddb =new SkillMasterDB();
JdbcHelper helper;
List<String> skdto = new ArrayList<String>();
skdto.add("asda");
skdto.add("rqwrq");
skdto.add("!####");
skdto.add("9087907");
skdto.add("./,/");
skdto.add("[][][]");
setSkillMasterData(skdto);
return SUCCESS;
}
Finally, you can test with Firebug's Net module what is going out of your page, check the radio parameter value now and after the edit to see what is going wrong now and how it will be going (hopefully) right later...