Why can't I access managed bean methods from a JSF2 page? - file-upload

In a <rich:popupPanel /> I have a <rich:fileUpload /> which has a fileUploadListener defined as #{assemblyMB.listener}. This listener method is defined on the managed bean as:
public void listener(FileUploadEvent event) throws Exception {
System.out.println("listener");
}
on the JSF page I have:
<rich:fileUpload id="popupFileUpload"
fileUploadListener="#{assemblyMB.listener}"
onuploadcomplete="#{rich:component('popup')}.hide(); return false;"
</rich:fileUpload>
On the managed bean, I have declared the annotation #ManagedBean(name = "assemblyMB").
I intend to access the method on the managed bean when the file is uploaded, but I'm failing to do so. I don't understand why is that happening.
Can anybody throw me a light here? Thanks in advance,
gtludwig

Assuming RichFaces 4.0, all you need to ensure is that the parent <h:form> is set to encode the request body as multipart/form-data.
<h:form enctype="multipart/form-data">
This way the file should be uploaded properly and the listener method should be invoked when the upload has been arrived in the server side.

Related

Blazor HttpClient injection into a ViewModel constructor

I am following the referenced blog/article below, and I am unable to inject an HttpClient to my ViewModel. It works fine the default way (#inject in the razor file). But i am trying to inject into the ViewModel instead.
If i add to the services like the following, then the default injection doesnt work for other razor views which has the #inject HttpClient.
// manually add HttpClient to services.
services.AddTransient<IFetchViewModel, FetchViewModel>();
Question:
How can i inject the default injected HttpClient to my various
ViewModels?
Note that I am getting an exception:
WASM: Unhandled exception rendering component:
WASM: System.Reflection.TargetParameterCountException: Number of parameters specified does not match the expected number.
Reference:
https://itnext.io/a-simple-mvvm-implementation-in-client-side-blazor-8c875c365435
Update
After making suggested changes and then digging deeper during
debugging, i can see that there is something wrong with the json
deserialization. Could this be an issue?
https://github.com/aspnet/Blazor/issues/225
Note that deeper down the exception stack trace, i see the following:
WASM: at SimpleJson.SimpleJson.DeserializeObject (System.String
json, System.Type type, SimpleJson.IJsonSerializerStrategy
jsonSerializerStrategy) <0x2ebc4f0 + 0x00068> in
<8f8c03446dbf45f5bbcb1e109a064f6e>:0 WASM: at
SimpleJson.SimpleJson.DeserializeObject[T] (System.String json)
<0x2ef2490 + 0x0000a> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0 WASM:
at Microsoft.JSInterop.Json.Deserialize[T] (System.String json)
<0x2ef2458 + 0x00004> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0 WASM:
at
Microsoft.AspNetCore.Components.HttpClientJsonExtensions.GetJsonAsync[T]
(System.Net.Http.HttpClient httpClient, System.String requestUri)
<0x33182e0 + 0x000fa> in <13ab8f8dacb6489b93c9655168c56037>:0 WASM:
at WebUI.Features.Fetch.FetchViewModel.LoadAsync () <0x3300de0 +
0x00102> in :0
Updated 2
So i can confirm now that i was barking up the wrong tree.
Essentially, i had a deserialization issue. Once i resolved that issue, everything is working fine. Not sure if i had a DI issue from the beginning or not. Nonetheless, my issue resolved now. Thanks for all the enlightening perspectives.
This is not really an answer to your question; without complete display of your code, no answer is really possible. But let me relate to the following code snippet; perhaps the problem lies there:
// manually add HttpClient to services.
services.AddTransient<IFetchViewModel, FetchViewModel>();
HttpClient service is provided as a Singleton (CSB) by the Blazor framework. Thus you cannot inject HttpClient into a service which you add to your app as Transient. Your service should also be added as Singleton...
Hope this helps...
[Edit]
How can i inject the default injected HttpClient
to my various ViewModels?
If your ViewModels are Components, you may use the #inject directive like this:
#inject HttpClient httpClient
If your ViewModels are ordinary classes (.cs), you can
either pass a reference to an HttpClient object from your calling component methods or inject the HttpClient service to your ViewModels' constructors. Don't forget to add your Services or ViewModels in the Startup class:
services.AddSingleton<IFetchViewModel, FetchViewModel>();
Once again, use AddSingleton
No, your problem has got nothing to do with issue 225.
This issue is very old, and all the bugs referred to in this issue were rectified long before I've heard of Blazor...
Note: The exception stack trace clearly points out in the direction of HttpClient being the culprit. Do what I've suggested above, and tell us if the issue is still persisting.
Why don't you display your code, as others ask you to do. Please look for instruction on how to ask question in stack overflow.
The pattern is easy.
I got it working like this, starting from the standard starter template.
In FetchData.razor:
#page "/fetchdata"
#using ClientBlazor1.ViewModels
#inject FetchDataViewModel vm
... the html
protected override async Task OnInitAsync()
{
forecasts = await vm.GetForecasts();
}
And the ViewModel is below. You seem to be missing the constructor (-injection) part here.
Using an interface is optional, I didn't.
public class FetchDataViewModel
{
private HttpClient _httpClient;
public FetchDataViewModel(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<WeatherForecast[]> GetForecasts()
{
return await _httpClient.GetJsonAsync<WeatherForecast[]>("sample-data/weather.json");
}
}
and to finish it up, the registration part in Startup.cs :
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<FetchDataViewModel>();
}
In general this should not be a Singleton.

JSF 2.2.10 file upload not working [duplicate]

This question already has an answer here:
Upgrade JSF / Mojarra in JBoss AS / EAP / WildFly
(1 answer)
Closed 5 years ago.
Issue: Action method and setter for file not getting called on file upload.
I did see the link for JSF 2.2 not working, but it is over 4 years old and I thought the problem should have been resolved. I am posting this since I am facing it today!
I am using JSF 2.2.10, JBoss 6.4; I have mojarra set up in JBoss config as follows: (in \modules\system\layers\base\org\jboss\weld\core\main and \modules\system\layers\base\org\jboss\as\weld\main)
I have set up my xhtml and Controller as follows. Would greatly appreciate if you could point out what I am missing. Been stuck with this for more than a day now!
<h:form id="massUpload" enctype="multipart/form-data">
<div class="col-xs-3 col-md-3">
<h:inputFile id="file" value="#{controller.uploadedFile}" />
<h:commandButton value="Upload"
action="#{controller.massUploadBranchGLInfoViaFile}"/>
</div>
</h:form>
Controller As follows:
#Named("controller")
#ViewScoped
public class MyController
extends AccessController
implements Serializable
{
private Part uploadedFile;
public String massUploadBranchGLInfoViaFile() throws IOException {
InputStream stream = uploadedFile.getInputStream();
addSuccessInfoToFlash("update-gl-success");
return "Success";
}
public void setUploadedFile(Part file){
this.uploadedFile = file;
}
public Part getUploadedFile(){
return this.uploadedFile;
}
}
Thank you very much
Karthik
Found (at least part of) the issue: Had to add the multipart-config to servlet configuration in my web.xml. That resolved calling the action and set methods. Am getting a NULLPointerException now. But one issue at a time I guess :)

RestEasy #ValidateRequest is not working

I am having below configuration for a RestEasy Rest WS
jaxrs-api-2.3.5.Final.jar,
resteasy-jaxrs-2.3.5.Final.jar,
resteasy-hibernatevalidator-provider-2.3.5.Final.jar,
hibernate-validator-4.3.2.Final.jar,
validation-api-1.0.0.GA.jar
I have added #ValidateRequest on class(tried on method as well) to validate any request input data before processing the request but i dont know why validation in not being invoked.
#Path(value = "/events")
#ValidateRequest
public class EventRestController {
#GET
#Produces({ MediaType.APPLICATION_XML, ACCEPT_HEADER })
public Response get(#QueryParam("componentSerialNumber") #NotNull String componentSerialNumber) {
System.out.println("powerChangeEvevnt.getComponentSerialNumber() " + componentSerialNumber);
return Response.ok().build();
}
}
i dont know what i am missing.
please suggest.
Turning on auto scanning of Rest resources and providers solved the issue, validation started working.
just set resteasy.scan parameter value to true in web.xml
i had explicitly registered all resources in a subclass extending javax.ws.rs.Application class but it was not considering HibernateValidator as a validator for validation. i found registering HibernateValidator as a validator quite complex, so just removed this explicitly registered configuration class and enabled Automatically scan.

Primefaces fileupload mode="Simple" with commandbutton ajax="true" throws nullpointer exception

This is in reference to the following thread
[File upload doesn't work with AJAX in PrimeFaces 4.0/JSF 2.2.x - javax.servlet.ServletException: The request content-type is not a multipart/form-data
The problem I experience is Nullpointer on clicking the command button.
Starting from the web.xml
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>
xhtml
<p:fileUpload id="file" value="#{userBean.uploadedFile}"
mode="simple" required="true" allowTypes="*.xls,*.xlsx"
requiredMessage="#{msg.vrUserUpload}"
invalidFileMessage="#{msg.vrUserUploadInvalidFile}"
multiple="false" fileUploadListener="userBean.fileUploadListener" />
<p:commandButton id="btnUpload" value="#{displayText.btUpload}"
styleClass="button_lite" actionListener="#{userBean.insert}"
ajax="true" update="userMassUploadForm"
process="userMassUploadForm">
</p:commandButton>
UserBean.java
public void fileUploadListener(FileUploadEvent event)
{
uploadedFile = event.getFile();
}
public void insert(){
if(uploadedFile!=null){
System.out.println(uploadedFile.getFileName());
}
else{
System.out.println("The file object is null.");
}
}
Console prints out "The file object is null." whenever ajax="true" and when set to false, works. I could not find a solution for this in the above referred thread.
Please advise.Also please let me know if you want any further information.
From PrimeFaces user guide:
Simple File Upload
Simple file upload mode works in legacy mode with a file input whose value should be an UploadedFile instance. Ajax uploads are not supported in simple upload.

spring-boot property placeholder

I'm not able to figure out why I am not able to inject values into my application.properties file in spring-boot. external property into the logging.file variable. I have an application.properties file which looks like this
logging.file=${mylogfile}
server.port=${myport}
with corresponding Spring-boot Application class
#PropertySources({
#PropertySource("file:///c:/myfolder/externalprops.properties"),
})
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
and external property file
mylogfile=myoutput.log
myport=8060
When I run my spring-boot 1.0.2.REL application I get the following exception every time I try to inject mylogfile into the logging.file property in application.properties
Exception in thread "main" java.lang.IllegalArgumentException: Could not resolve placeholder 'mylogfile' in string value "${mylogfile}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
Note that I am not having any problems injecting and starting up the application if I inject the server port number on its own.
I am going around in circles on this issue and cannot figure out what I am doing wrong.
I don't think you can use #PropertySource to inject values into "application.properties" - the latter has to be parsed and ready to use before any #Configuration is read, or even known about. Your external properties could go in "${user.dir}/application.properties" and I think that would achieve what you are trying to do.