I am developing a struts2 application (Struts 2.3.14, java 1.7, on a Tomee plus 1.5.1 server).
I have a bunch of "detail" actions, and all of them contain the following code:
private Long modelId;
public Long getModelId() {
return modelId;
}
public void setModelId(Long modelId) throws Exception {
this.modelId = modelId;
(...some other stuff...)
}
In every action I also have a "persist" action that I use to save data, like this one:
#Action(value = "persistEntity", results = {
#Result(name = "success", location = "entityDetail",
type = "redirectAction", params = {"modelId", "%{modelId}"})
})
public String persist() throws Exception {
this.modelId = [save method invocation]
return "success";
}
After saving I try to redirect the user back to the detail page, but I get the following error:
Unexpected Exception caught setting 'modelId' on 'class classpath.DetailAction':
Error setting expression 'modelId' with value '[Ljava.lang.String;#43b5d2fe'
So, it seesm like Struts is handling my masterId as a String array... I had a look at this question, but it was no help for me.
What is most strange to me, after I get this error I get the same error every time I try to enter an existing entity, but if I restart my application I can enter existing entities without any error.
Thank you!
Well, turns out I was misleaded by Struts2 error message... The framework was correctly trying to set the parameter in my action, but I had an exception thrown by the
(...some other stuff...)
section. I went through the whole log file, and finally found the real issue.
Thank you anyway.
Related
I'm using mysql for my db, spring for my backend and angular for my frontend. my frontend is throwing this weird bug when its routed proper: click here to see it
as you can see, the path at the end is %7Bid%7D (looks like {id} from the backend)
the http error code is always one of 3: 400,400 or 500
the backend looks okay and I've only really ever gotten this error code:
2022-02-04 15:30:31.465 WARN 15200 --- [nio-8081-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "{id}"]
here is the controller in question(a get request):
#CrossOrigin
#RestController
#RequestMapping(path = "/api/patient")
public class PatientPortalController {
#Autowired
private PatientPortalRepo patientPortalRepo;
#PostMapping("/patientportal")
public PatientPortal createPatientPortal(#RequestBody PatientPortal patientportal) {
return patientPortalRepo.save(patientportal);
}
#GetMapping("/patientportal/{id}")
public ResponseEntity<PatientPortal> getpatientPortal(#PathVariable Long id){
PatientPortal patientportal = patientPortalRepo.findByPatientPortalId(id);
if(patientportal.getId()>0 && patientportal!=null)
return new ResponseEntity<PatientPortal>(patientportal, HttpStatus.OK);
return new ResponseEntity<PatientPortal>(patientportal, HttpStatus.BAD_REQUEST);
}}
Some things worth of note that I've tried with the backend
Tried changing response entity to of type long and returning id, tried refactoring the controller numerous times, tried changing decorators/paths around, 20x checked the types are correct, checked if any types other than the id are throwing it, checked if I had any security implemented that was denying access, checked if adding a onetoone would get it to pop up on the front end. It works fine on the backend(returns a list of what I'd assume is patientportal object) but I am either routing incorrectly, there is some security I'm missing, there is some type error, or there is some logic errors. I think however the issue lies in the front end.
here's the code where I call the front end method hard coded a value to test:
this.patientloginservice.loginPatient(this.patient).subscribe(data=>(this.route.navigate(['api/patient/patientportal/1'])),error=>console.log('error'));
and here is where that code is serviced:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http'
import { Observable } from 'rxjs'
import { PatientPortal } from './patientportal';
#Injectable({
providedIn: 'root'
})
export class PatientService {
private baseURL = "http://localhost:8081/api/patient/patientportal";
constructor(private httpClient: HttpClient) { }
getPatientPortalList(): Observable<PatientPortal[]> {
return this.httpClient.get<PatientPortal[]>(`${this.baseURL}`);
}
createPatientPortal(patientportal: PatientPortal): Observable<Object>{
return this.httpClient.post<Object>(`${this.baseURL}`, patientportal);
}
getPatientPortalById(id: number): Observable<PatientPortal>{
return this.httpClient.get<PatientPortal>(`${this.baseURL}/{id}`);
}
updatePatientPortal(id: number, patientportal: PatientPortal): Observable<Object>{
return this.httpClient.put(`${this.baseURL}/{id}`, patientportal);
}
deletePatientPortal(id: number): Observable<Object>{
return this.httpClient.delete(`${this.baseURL}/{id}`);
}
}
any help will be much appreciated, thank you. again like I said the route routes correctly as far as I can tell, but the rendered table does not fill data and it throws that error. I am using a login that is to redirect/route to a patient's details.
You're using Template literals incorrectly.
Instead of just {id} it should be ${id} just like what you did with ${this.baseUrl}
Hope that solves your issue.
I'm quite new for spring and JUnit. Now I try to build a test case. after I run this one
#Test
public void shouldBeOK_Found() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.delete("/scores/{id}", 1L)
).andExpect(status().isOk());
}
I get this error trace.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: Name for argument of type [long] not specified, and parameter name information not found in class file either.
Here is my controller
//Delete Score
//DELETE /score/{id}
#DeleteMapping("/scores/{id}")
public ResponseEntity<Score> deleteScore(#PathVariable(required = true) long id) {
Score result = null;
try{
Optional<ScoreEntity> s = scoreRepository.findById(id);
if (s.isPresent()){
result = new Score(s.get());
scoreRepository.delete(s.get());
return ResponseEntity.status(HttpStatus.OK).body(result);
}
}catch (Exception e){
System.out.println(e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
Please help. Thank you in advance.
You need to define the name in the annotation if your code is not compiled with -parameter for Java 8 doc.
You can explicitly name URI variables (for example, #PathVariable("customId")), but you can leave that detail out if the names are the same and your code is compiled with debugging information or with the -parameters compiler flag on Java 8.
#PathVariable(required = true, name="id") long id
I'm currently using a Spring Boot application I'm tinkering around the the error page and the messages given to it. Currently I can change the HTTP Status Number and Message, but I'm not sure how to change the "Unknown reason" or Description without changing it to something besides 418. Is there a way to customize those as well, or am I stuck with the embedded code provide?
Current Code Tinkering
for(String serialNo : serialNoList) {
if(serialNo.length() < MIN_SERIALNO_SIZE ) {
response.sendError(401, "Serial Number Length Exceeded: " + serialNo);
}
if(serialNo.length() > MAX_SERIALNO_SIZE) {
response.sendError(403, "Serial Number Legth Too Short: " + serialNo);
}
}
First, you need to disable whiteLabel error pages.
server.error.whitelabel.enabled=false
or
// adding this on your main class
#EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})
Now, create a html page (error.html), which you want to display and place it in resources/templates directory, it will be picked automatically.
To customize, differently for each error you can implement ErrorController.
#Controller
public class CustomErrorController implements ErrorController {
// override this error path to custom error path
#Override
public String getErrorPath() {
return "/custom-error";
}
#GetMapping("/custom-error")
public String customHandling(HttpServletRequest request){
// you can use request to get different error codes
// request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)
// you can return different `view` based on error codes.
// return 'error-404' or 'error-500' based on errors
}
}
I'd like to redirect the user to an error page from within an Advice without having to throw an exception if a param is not specified. Is that possible? If so, how can I do it?
I'm currently throwing an exception but I feel it's overkill and the log it leaves is too much:
#Aspect
#Component
public class ParamTracker{
private static final Logger logger = LogManager.getLogger("ParamTrackerLogger");
#Before("execution(* com.controller.MainController.*(..)) && !execution(* com.controller.MainController.doNotUseThis(..))")
public void trackParam(JoinPoint point) throws Exception {
String methodName = point.getSignature().getName();
String param = point.getArgs()[0].toString();
if(param.isEmpty()) {
logger.error("Param is empty");
throw new Exception("Please specify param");
} else {
logger.info(param + ". " + methodName);
}
}
}
Having the user redirected to an error page and a simple Param not specified. Redirecting to error page ... on the log would be ideal. Also, it doesn't have to be a #Before, as long as it works.
Thanks in advance.
I think one possible solution might be something like this:
You can write a custom exception for when a param is invalid. eg ParamIsEmptyException.
When param is empty, throw above exception instead of normal exception.
In your central exception handler(if you don't have it, you can simply make it), check the exception type, if the exception has ParamIsEmptyException type, you can use HttpServletResponse.sendRedirect method for redirecting user to any url.
I am new to building web applications using spark java.
I am trying to use 'Before' filter but getting the below error. please help. I have pasted my code below.Bootstrap is my class having the main method.
Error: "The method before is undefined for the type BootStrap"
public class BootStrap {
public static void main(String[] args) throws Exception {
ipAddress("localhost");
port(3003);
staticFileLocation("/public/html");
before((request, response) -> {
String user = request.queryParams("user");
String password = request.queryParams("password");
String dbPassword = usernamePasswords.get(user);
if (!(password != null && password.equals(dbPassword))) {
halt(401, "You are not welcome here!!!");
}
});
}
I think it's just lacking to statically import Spark.*;
Not sure this helps, but according to this "Access-Control-Request-Method" is a request header, not a response header. That said, a 404 always shows that the resource you want to find does not exist. Are you sure your url is correct?