Jf Okeeffe

Greenhorn
+ Follow
since Nov 11, 2020
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Jf Okeeffe

Tim Holloway wrote:The operation is failing because you've told Spring to jam a non-numeric value ("wer") into the numeric CRUDRepository ID.



If that is the case why is it that it works (with any string such as "wer") if I change the attribute "test" to a name that is different than the class name?
It would be just a change in the attribute name, not a change on types.
2 days ago
No. Because like I said, if I change the attribute name of the class to a name that is different than the class name the error will not occur. Even if I input a string in that field.
And if you take a look at the code the field is a string (private String test), not an int.
Looks like spring is doing that type of conversion in the backstage somehow when using CrudRepository.
I'm nowhere assigning that content to an int. Spring seems to be doing it.
2 days ago
"wer" is the content I filled in the input box and then clicked save.
Could have filled with anything else.
2 days ago
To understand you would need to reproduce the error I refer to in the original post here.
There is a link there to download the code.
2 days ago

Tim Holloway wrote:Having a property named "person" within class Person is totally OK with Spring, though...



Not really. That is exactly what I pointed out in the original post here.

See where I said:

Jf Okeeffe wrote:It doesn't work when there's a class attribute that has the same name of the model class name (ex Class Test with attribute test).



But that error only happens when using CrudRepository as I also pointed out in the original post.
When not using it, Spring doesn't complain as you said.
2 days ago

Junilu Lacar wrote:English can't be "basic" in itself.



Sorry if I was not clear.
I didn't mean the profficiency of english being basic in itself.
I meant the profficienty of a person in that specific language being basic.
My example is of a language class associated with a person class (just like you suggested) where the language class would represent all of the languages a person is skilled at and the persons profficiency level (basic, fluent...) on each one.

Anyway, even if you don't like my example (and it might not be one of the best indeed) I think we can't presume that needing to have an attribute with the class name would never be necessary. Someone somewhere might need it. Just like I needed it. And in fact, I'd say this is pretty common to be done as java (without spring crud repository) allows it. So I believe would be good if spring allowed it as well letting the developer decide how it would like to do.
2 days ago
How to pass a list from the view to the controller in Spring MVC with thymeleaf?

I have an html page to edit a list of persons.
When the page is opened the controller gets the list of persons from the db and binds to the view.
That works fine.

Then the user edits the data and clicks save.
Now I need to submit the edited data of each person to the controller so that the controller can save the edits.

I'm trying to do that using @ModelAttribute ArrayList<Person> as shown below but it's not working.
The arraylist comes empty.

How do I do for the arraylist to come filled with all of the persons objects from the form?

View


Controller
3 days ago

Stephan van Hulst wrote:Which I think is good advice regardless of Spring, because what does it even mean for a class "Person" to have a field named "person"?



I agree that in this "Person" example doesn't make much sense. But there are cases it does make sense. For instance, if you have a class called "Language" with an attribute that is also called "language" (english, spanish...) and an attribute "profficiency" (basic, fluent...).
3 days ago
Here is what shows in the browser. In the Spring Tool Suit console no error is displayed.

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sat Nov 21 16:08:42 BRT 2020
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'projetos.model.Pessoa'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value 'wer'; nested exception is java.lang.NumberFormatException: For input string: "wer"
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'projetos.model.Pessoa'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value 'wer'; nested exception is java.lang.NumberFormatException: For input string: "wer"
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:79)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53)
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:693)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttributeFromRequestValue(ServletModelAttributeMethodProcessor.java:142)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:78)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:139)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value 'wer'; nested exception is java.lang.NumberFormatException: For input string: "wer"
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
at org.springframework.data.repository.support.DomainClassConverter$ToEntityConverter.convert(DomainClassConverter.java:177)
at org.springframework.data.repository.support.DomainClassConverter.lambda$convert$0(DomainClassConverter.java:85)
at java.base/java.util.Optional.map(Optional.java:258)
at org.springframework.data.repository.support.DomainClassConverter.convert(DomainClassConverter.java:85)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:129)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
... 52 more
Caused by: java.lang.NumberFormatException: For input string: "wer"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.valueOf(Integer.java:983)
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:211)
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:64)
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:50)
at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
... 62 more
1 week ago
Well, in the real project I do use it.
But in this test I removed it and the error still happens.

In fact, I still have these two lines (it's in the downloadable project I provided):

import projetos.repository.PessoaRepository;

@Autowired
private PessoaRepository pessoaRepository;

So, given your comment, I decided to comment those two out as well to see if the error would stop happening. No difference. The error continues there.

But if I go to the repository class and remove "extends CrudRepository<Pessoa, Integer>" the error stops happening.

So seems that even if the repository is not used, just for the fact that extending CrudRepository is there, something is being executed in the Spring backstage that is causing this error.
1 week ago
I have an HTML page with a text field and a button.

When I fill the field and click enter I get the following error.

Failed to convert value of type  'java.lang.String' to required type '...model.Test'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value 'typedvaluehere'

The code is below.

One interesting thing I noted is that when I remove extends CrudRepository<Test, Integer> from the repository, the error stops happening. But I can't do that, because I need it. But shows it seems to be a conflict with CrudRepository.

Another interesting thing I noted is that if I change "private String test" in the model to something else such as "private String name" and update getters/setters, it will work fine. Even with the CrudRepository. It doesn't work when there's a class attribute that has the same name of the model class name (ex Class Test with attribute test).

The complete project is available for download at: https://drive.google.com/file/d/1qfn73uGH6eUmJf8vtWZvbSn2IQiI0MzB/view?usp=sharing

AddTest.html



Controller




Model




Repository

1 week ago
Hi Ishan,

Yes, that's pretty much what I did, with the addition of @ModelAttribute to be able to pass the object to the second method controller. Worked as needed.

Thank you all for your contributions.
2 weeks ago
Hi Paul,

Thanks for your insights. They are very helpful.

I should mention I’m new to java/spring mvc but not new to web development.
I come from asp.net c#.

Paul Clapham wrote:The address bar does indeed reflect the content on the page. It reflects where the page came from, that's how HTML works.



I agree. And that is what I want. Don’t want to do nothing different than what http/html standards provide.

If we use simple html this is how it would work.

Form1.html
<form action="form2.html" method="post">
<input type="submit" value="Submit"/>

Form2.html
<body>
Form2.html is open and the url displayed is /form2.html
</body>

1. User types .../form1.html at the browser and clicks enter
2. form1.html content is displayed and url correctly is /form1.html (as that was the requested url).
3. User clicks the submit button
4. Form2.html content is opened and the url /form2.html is correctly displayed

The final outuput is the form2.html content and a matching url (http://localhost:8080/form2).
So it works just as I want.


The thing is that with Spring MVC, you add one additional step (the controller in the middle).
1. User types .../form1.html at the browser and clicks enter
2. form1.html content is displayed and url correctly is /form1.html (as that was the requested url).
3. User clicks the submit button.
4. Form action submits the form not to form2.html directly, but to a spring mvc controller on the server side. <form action="saveform1" method="post">.
5. Controller method that maps “saveform1” is called (controller method with the modelandview code I sent previously), processes code (saves data to db...), and finally calls form2.html with the following code:
ModelAndView modelAndView = new ModelAndView("form2");
6. Form2.html is correctly presented to the user, binding data from the object in the controller. But the url is what’s mapped in the controller (http://localhost:8080/saveform1), not the html that was called inside the controller (http://localhost:8080/form2).


So the additional spring mvc method (controller) makes the post request of the button make two calls instead of one (saveform1 first and form2 second).
And for it to have the same end result to the user(as it had on pure html) I think http://localhost:8080/form2 should be the final displayed url to the user (as that is what was lastly requested in this process and is what is being finally displayed).

So I understand this is a Spring MVC thing and how it is implemented, not a http/html thing that would need to be changed.

For instance, if we go to asp.net this is how the flow goes.

1. User types .../form1.aspx at the browser and clicks enter
2. form1.aspx content is displayed and url correctly is /form1.aspx (as that was the requested url).
3. User clicks the submit button.
4. A button onclick event is called on the server side to execute whatever you want. Just like you would do at the spring mvc controller (for instance, saving some data on the db). Then you can redirect the user to form2 with a Response.Redirect("/form2.aspx").
5. form2.aspx content is returned to the user and the url displayed is http://localhost:8080/form2.aspx (not a url in the middle like /saveform1).

I just want to do the same here.

And asp.net uses the same http protocol.
That’s why I understand this is more of a Spring MVC thing and how to use it, than a need to change html or http protocol.

Anyways, after some digging I’m glad to say I found out how to make this work on Spring MVC! I knew there should be a way to do it

In fact, it's pretty simple.

You just need to add a @ModelAttribute annotation to the controller method, add the saved object to that using addFlashAttribute and do a return "redirect:/form2". Then on Form2 controller retrieve the object from @ModelAttribute, bind to the form2.html and return form2. That will display form2 fields (filled with the object data) and also show form2 url (as it is supposed to since form2 is what was requested to the server). Gotcha!

Anyways, I appreciate you guys time and willingness to help.

As I said, I'm new to spring mvc and will certainly come back for more help from you guys in the future.

This was a great discussion. Appreciate anything else you have to add.

Best regards.
2 weeks ago
But I'm new to spring mvc. So am open to learn how other seasoned spring mvc developers design their apps in this sense.

Would you guys leave http://localhost:8080/saveuserphones at the url in this case or would you prefer to do the same I'm trying to achieve (address bar show the url of the hmtl that is actually being displayed)?

Or is there any other better recommended design for this kind of thing?
3 weeks ago
Hi Paul,

I respect your position. But I prefer to do it a little different.

Let's say form1.html is really called "adduserphones.html" and form2.html is called "addusereducation.html".

When the user is at form2(filling the fields from addusereducation.html) he should be looking at the url http://localhost:8080/addusereducation, not the url http://localhost:8080/saveuserphones.

It's what makes more sense in my understanding.

It should be as if http://localhost:8080/addusereducation was directly typed at the url and pressed enter.

I agree when you say that users shouldn't need to look at the url address bar. What is more important obviously is the page content. But I personaly like my address bar to reflect the content on the page. So, would like to design my app that way.

So the point here is just to ask if it is possible or not with spring mvc. And if it's possible, how to do it.
3 weeks ago