Although I know that StackOverflow has already setRequestProperty function of HttpURLConnection question, I really don't understand what this method does. I cannot "step into" it (F7) when debugging. I pressed Ctrl-B to view the method's body, but it only has the following code:
public void setRequestProperty(String field, String newValue) {
checkNotConnected();
if (field == null) {
throw new NullPointerException("field == null");
}
}
and checkNotConnected:
private void checkNotConnected() {
if (connected) {
throw new IllegalStateException("Already connected");
}
}
I mean that where is the code that puts the value to the field? Any explanation is appreciated.
UPDATE (2015/08/08):
I have found the way to view its implementation. Since it's abstract, must use Ctrl-Alt-B instead of Ctrl-B to view.
I guess you are accessing the wrong way, or have some kind of protected code...
The original function is this:
/**
* Sets the general request property. If a property with the key already
* exists, overwrite its value with the new value.
* ...
*/
public void setRequestProperty(String key, String value) {
if (connected)
throw new IllegalStateException("Already connected");
if (key == null)
throw new NullPointerException ("key is null");
if (requests == null)
requests = new MessageHeader();
requests.set(key, value);
}
Where requests.set(key, value) do what you're asking for :)!
this is back source code of setRequestProperty()
Sets the general request property. If a property with the key already exists, overwrite its value with the new value.
NOTE: HTTP requires all request properties which can legally have multiple instances with the same key to use a comma-seperated list syntax which enables multiple properties to be appended into a single property.
Parameters:
key the keyword by which the request is known (e.g., "accept").
value the value associated with it.
Throws:
java.lang.IllegalStateException
if already connected
java.lang.NullPointerException
if key is null
See also:
getRequestProperty(java.lang.String)
public void setRequestProperty(String key, String value) {
if (connected)
throw new IllegalStateException("Already connected");
if (key == null)
throw new NullPointerException ("key is null");
if (requests == null)
requests = new MessageHeader();
requests.set(key, value);
}
Source Link
I have found the way to view its implementation. Since it's abstract, must use Ctrl-Alt-B instead of Ctrl-B to view.
And the back source code of setRequestProperty as the following (inside jre\lib\rt.jar):
public void setRequestProperty(String var1, String var2) {
if(this.connected) {
throw new IllegalStateException("Already connected");
} else if(var1 == null) {
throw new NullPointerException("key is null");
} else {
if(this.isExternalMessageHeaderAllowed(var1, var2)) {
this.requests.set(var1, var2);
}
}
}
Related
Hi guys it is my addAll method and I think solving this way isn't optimize version, can you offer me a simpler version by the way. Any help into this would be appreciated!
#Override
public ApiResponse addAll(HttpHeaders headers, List<NewsDto> newsDtoList) {
for (NewsDto newsDto : Objects.requireNonNull(newsDtoList)) {
News news = new News();
if (newsDto.getUserId() != null) news.setUserId(newsDto.getUserId());
if (newsDto.getTitleRu() != null) news.setTitleRu(newsDto.getTitleRu());
if (newsDto.getTextRu() != null) news.setTextRu(newsDto.getTextRu());
if (newsDto.getTitleUz() != null) news.setTitleUz(newsDto.getTitleUz());
if (newsDto.getTextUz() != null) news.setTextUz(newsDto.getTextUz());
if (newsDto.getTitleEng() != null) news.setTitleEng(newsDto.getTitleEng());
if (newsDto.getTextEng() != null) news.setTextEng(newsDto.getTextEng());
newsRepo.save(news);
}
return new ApiResponse(true, "all list saved");
}
I try mapped with mapstruct but my entity class extend some fields at another class thats why mapstruct could't see any fields in class and I try solve this way.
Refactor your code slightly with the following considerations:
Your null checks aren't useful; if the field is null on one, it will be set to null on the other anyway. For example, in the original code you have:
if (newsDto.getUserId() != null) news.setUserId(newsDto.getUserId());
but if newsDto.getUserId() returns null then using this object on the setter doesn't change anything unless a default value is already presesnt.
So you can just write
News news = new News();
news.setUserId(newsDto.getUserId());
news.setTitleRu(newsDto.getTitleRu());
news.setTextRu(newsDto.getTextRu());
news.setTitleUz(newsDto.getTitleUz());
news.setTextUz(newsDto.getTextUz());
news.setTitleEng(newsDto.getTitleEng());
news.setTextEng(newsDto.getTextEng());
Or if you need some special logic for default values, you could make a method for that too
public String defaultValue(String raw) {
if (raw == null || raw.trim().isEmpty()) {
return null; // or return an empty string or whatever you want
}
return raw;
}
Then you can use this in your mapping method
News news = new News();
news.setUserId(defaultValue(newsDto.getUserId()));
news.setTitleRu(defaultValue(newsDto.getTitleRu()));
news.setTextRu(defaultValue(newsDto.getTextRu()));
news.setTitleUz(defaultValue(newsDto.getTitleUz()));
news.setTextUz(defaultValue(newsDto.getTextUz()));
news.setTitleEng(defaultValue(newsDto.getTitleEng()));
news.setTextEng(defaultValue(newsDto.getTextEng()));
The above code should be in its own method, something like
public News toEntity(NewsDto newsDto) {
... // see above
return news;
}
Then you can test this method for the conversion of one news dto to its respective entity class.
After that, use it in the loop you had:
#Override
public ApiResponse addAll(HttpHeaders headers, List<NewsDto> newsDtoList) {
for (NewsDto newsDto : Objects.requireNonNull(newsDtoList)) {
newsRepo.save(toEntity(newsDto));
}
return new ApiResponse(true, "all list saved");
}
You could use ModelMapper. It should map your DTO to Entity as long as the variable names match.
private static final ModelMapper modelMapper = new ModelMapper();
public static News convertNewsDTOToNewsEntity(NewsDTO newsDTO) {
return modelMapper.map(newsDTO, News.class);
}
this is the usual way
productMenu = productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId")));
if (productMenu != null) {
productPost.setProductMenu(productMenu);
}
can i do this not null object checking inside setter method
productPost.setProductMenu(productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId"))));
Trying to reduce the code. Would appreciate any sort of help.
Version >= Java 8
You could use Optional to ensure only non null value will be set.
Optional.ofNullable(request.getString("productMenuId"))
.map(value-> Integer.parseInt(value))
.map(productMenuService::getProductMenuById);
.ifPresent(productPost::setProductName);
Version < Java 8
void setProductMenu(*ProductMenuType* productMenu) {
// do all your checking before setting here
if (productMenu != null) {
productPost.setProductMenu(productMenu);
}
}
But your case doesn't make sense(no else part) because if we are not setting a value for a variable, then by default it will be NULL
if(productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId")) == null){
return new ResponseEntity<String>("Not found", HttpStatus.BAD_REQUEST);
}else{
productMenu = productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId")));
}
//in your repository first check that data is present or not like this
repository.findById(id).isPresent(){
return repository.getOne(id);
}else return null
Throw an exception.
If someone passes an invalid product menu ID to your application, they made a mistake. You should not act like they did nothing wrong. Your application certainly should not leave the old product menu in place and ignore the user’s request entirely.
if (productMenu == null) {
throw new RuntimeException("Invalid product menu ID.");
}
productPost.setProductMenu(productMenu);
While this won’t make your code shorter, it will make your code better.
A robust application does not pretend that it’s working when it is not in fact working. To do otherwise would frustrate users and would make debugging a lot more difficult, as it could be weeks or months or years before the problem is discovered.
Ideally, you will want to create your own exception class, and throw that instead:
if (productMenu == null) {
throw new InvalidProductMenuIDException("Invalid product menu ID.");
}
productPost.setProductMenu(productMenu);
where the exception class is simply:
public class InvalidProductMenuIDException
extends Exception {
public InvalidProductMenuIDException(String message) {
super(message);
}
public InvalidProductMenuIDException(Throwable cause) {
super(cause);
}
public InvalidProductMenuIDException(String message,
Throwable cause) {
super(message, cause);
}
}
I've got a bean that has a field of type List among other things.
public List<MyClass> getter() {
return field;
}
public void setter(MyClass[] source) {
this.field = Arrays.asList(source);
}
I've implemented a converter Converter<String, MyClass> and it works, too. If a string can be converted into MyClass, it's converted, and if not, an exception is thrown, and an instance of FieldError is included in Errors errors = binder.getBindingResult();. The problem is, the FieldError#getRejected method a String with a comma-separated list of both valid and invalid values, which can be misleading. And without a space, which is just ugly. Like this:
Field has invalid value of "valid,invalid"
while I would prefer
Field has invalid value of "invalid"
In other words, how to get the conversion and validation to work individually on each value?
Although spring's approach is not very intelligent, it's logically correct. The following code can help you find the invalid value.
FieldError fieldError = bindingResult.getFieldError();
if (fieldError != null && fieldError.contains(TypeMismatchException.class)) {
TypeMismatchException typeMismatchException = fieldError.unwrap(TypeMismatchException.class);
ConversionFailedException conversionFailedException = findConversionFailedException(typeMismatchException);
if (conversionFailedException != null) {
Object value = conversionFailedException.getValue();
// get the invalid field value
}
}
/**
* Recursively find the ConversionFailedException
* #param target
* #return
*/
public ConversionFailedException findConversionFailedException(Throwable target) {
Throwable cause = target.getCause();
if (cause == null) {
return null;
} else if (cause instanceof ConversionFailedException) {
return (ConversionFailedException)cause;
}
return findConversionFailedException(target);
}
I am coding a web-app in Java-EE and find myself with a very unexpected result when I am trying to display errors on user-input.
The app is built on the JSP/Servlet/Form/Bean model. Basically, the JSP stores data in the request, and transfers it to the servlet. Then the servlet transfers the request raw to the form, which then reads the data, performs the necessary checks and returns the bean to the servlet.
Most of the fields must have specific values, some others must simply be non-null.
I have written error detection code to secure inputs however I find myself with a very strange result:
when the field is non-null but the value is incorrect (say, an hour located outside the 00:00-23:59 range), it does return the proper error, along with the error message, stored in a HashMap, and I can access it in my JSP.
However, when the field is null, it returns the message, probably stores it in the HashMap as well (I know this because the ${!empty errors.dataErrors} test returns true and the error field is displayed in my JSP) but there's no way to access the values of the errors
I have searched through my code but still can't find where the error comes from. Here are snippets of it if someone knows where the problem comes from
doPost method from the servlet:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
NewBookingForm form = new NewBookingForm();
Booking booking = form.registerBooking(request);
String VUE;
request.setAttribute("booking", booking);
request.setAttribute("errors", form);
this.getServletContext().getRequestDispatcher(VIEW).forward(request, response);
}
the map is a field in the NewBookingForm class, declared and initialized outside the registerBooking method like this private Map<String,String> dataErrors = new HashMap<String,String>(); and it has a private setter (for access within the class) and a public getter (for access in the Servlet and in the JSP)
inside the form class, I use this function to get the field values:
private static String getFieldValue(HttpServletRequest request, String fieldName)
{
String value = request.getParameter(fieldName);
if (value == null || value.trim().length() == 0){return null;}
else{return value;}
}
After getting the values with a series of calls like String fieldDepartureStation = getFieldValue(request, FIELD_DEPARTURE_STATION); at the beginning of my method, I then check them using try/catch blocks like this
try
{validation.departureStation(fieldDepartureStation);}
catch(Exception e)
{setDataErrors(FIELD_DEPARTURE_STATION, e.getMessage());}
The validations method within the validation class are a bit different if the data must have specific value-ranges or must simply be non-null.
In the former case, they are something like this:
public void departureTime(String time) throws Exception
{
if (!validationRETime(time)) { throw new Exception("Please input a time with the hh:mm pattern"); }
}
....
private boolean validationRETime(String strTime)
{
String regExp = "^([01][0-9]|2[0-3])[:][0-5][0-9]$"; // hh:mm
if (strTime.matches(regExp))
{
return true;
}
else
{
return false;
}
}
whereas in the latter case they are simply
public void departureStation(String station) throws Exception
{
if (station.equals(null)) { throw new Exception("Please input a departure station"); }
}
Finally, in my JSP, I use the following code to display errors:
<c:if test="${!empty errors.dataErrors}">
<p>Errors</p>
<c:forEach items="${errors.dataErrors}" var="message">
<p><c:out value="${message.value}" /></p>
</c:forEach>
</c:if>
And it does display the Error paragraph when I purposedly enter incorrect values, but the <c:forEach> is only looping and displaying the error messages when the wrong field is non-null but with an incorrect value. Thus with a field that only needs to be non-null, I never get the message (but I do get the error)
These are all the things I could think of that could possibly go wrong, but I have yet to discover where they did and if someone could help me, I'd be very glad.
The problem is in your departureStation method: -
public void departureStation(String station) throws Exception
{
if (station.equals(null)) {
throw new Exception("Please input a departure station");
}
}
Your test for null value is itself triggering a NPE. So, as soon as station.equals(null) is executed for station = null, a NPE exception is thrown, which is then propagated to the caller. So, your if block will not even be executed. And hence you are not throwing the Exception as you might be thinking.
Now, also note that, the NPE that is thrown does not contain any message. So, e.getMessage() will return null on it.
Now, let's move back to the caller: -
try
{validation.departureStation(fieldDepartureStation);}
catch(Exception e)
{setDataErrors(FIELD_DEPARTURE_STATION, e.getMessage());}
Here you are doing the biggest Crime in the world of Exception Handling, by using a catch block for Exception. Since Exception is the super class of all the exceptions, it will handle all the exceptions in the same way. So, it consumes the NPE, and passes it to setDataErrors().
So, you will of course get the errors, but, the value e.getMessage() will be null. And that is why you are not seeing any message. You can even test it by logging the value of e.getMessage() in the catch block above.
Solution ??
Just change your null check with this one: -
if (station == null) {
throw new Exception("Please input a departure station");
}
And everything will be ok. I think, you will have to do this change in all of your methods. Always perform the null check using == operator.
public class Test {
public static void main(String[] args) {
Test c = new Test ();
try {
c.departureTime("30:30");
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
c.departureTime(null);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void departureTime(String time) throws Exception {
if (!validationRETime(time)) {
throw new Exception("Please input a time with the hh:mm pattern");
}
}
private boolean validationRETime(String strTime) {
String regExp = "^([01][0-9]|2[0-3])[:][0-5][0-9]$"; // hh:mm
if (strTime.matches(regExp)) {
return true;
} else {
return false;
}
}
}
You will figure out your problem by running above code. Simply putting, you need to make sure exp.getMessage() always has value. To fix the issue, you might want to tweak your departureTime() method to provide more fine-grained exception handling.
I need to check if an exception is caused by some database problem. I receive an Exception and check if its cause contains the "ORA" string and return that (something like "ORA-00001"). The problem here is that the exception I receive is nested inside other exceptions, so if I don't find out if it's an oracle exception, I have to check into the cause of that exception and so on.
Is there a cleaner way to do this? Is there a way to know the first cause (the deep-nested exception) of a given exception?
My current code looks like this:
private String getErrorOracle(Throwable e){
final String ORACLE = "ORA";
if (e.getCause() != null && e.getCause().toString().contains(ORACLE)){
return e.getCause().toString();
} else if(e.getCause() != null){
return getErrorOracle(e.getCause());
} else {
return null;
}
}
In the interests of not reinventing the wheel, if you're using Apache Commons Lang, then look at ExceptionUtils.getRootCause().
Is it worth including a library just for that? Maybe not. But if you already have it on your classpath, it's there for you, and note that it does some things that a 'naive' implementation might not do (e.g. deal with cycles in the cause chain... ugh!)
If you are already on Guava than Throwables.getRootCause() comes to the rescue.
Just traverse the exception chain until you get to an exception with no cause, and then just return that message, if you want the last one.
Your function will only get the first cause, if there is one.
You may want to look at finding the first cause in your package though, as the actual deepest one may be an oracle exception, which is helpful, but unless you can see where you created the problem, you will have a hard time fixing it.
Probably a bit overkill for your usage but I think it is cleaner (and reusable)
interface ThrowablePredicate {
boolean accept(Throwable t);
}
public OracleErrorThrowablePredicate implements ThrowablePredicate {
private static final ORA_ERR = "ORA";
public boolean accept(Throwable t) {
return t.toString().contains(ORA_ERR);
}
}
public class CauseFinder {
private ThrowablePredicate predicate;
public CauseFinder(ThrowablePredicate predicate) {
this.predicate = predicate;
}
Throwable findCause(Throwable t) {
Throwable cause = t.getCause();
return cause == null ? null
: predicate.accept(cause) ? cause : findCause(cause)
}
}
// Your method
private String getErrorOracle(Throwable e){
return new CauseFinder(new OracleErrorThrowablePredicate()).findCause(e);
}
I think that any error that is thrown by oracle will be wrapped in a SQLException (somebody please correct me if wrong). Once you have accessed the SQLException you should be able to call
getErrorCode()
Retrieves the vendor-specific exception code for this SQLException object.
Let me know if this works as I have never tried it :-)
Karl
You could improve your code checking for SQLException
import java.sql.SQLException;
private static final String ORACLE = "ORA";
public String doHandle(Throwable t) {
if (t.getClass().isAssignableFrom(SQLException.class)) {
SQLException e = (SQLException) t;
int errCode = e.getErrorCode();
String state = e.getSQLState();
String msg = e.getMessage();
if (msg.contains(ORACLE)) {
return msg;
}
} else {
if (t.getCause() != null) {
return this.doHandle(t.getCause());
}
}
return "";
}
Also, I think in Oracle "errCode" contains the number associated to ORA-nnnn
In my Spring Boot project for getRootCause IDEA suggest 3 static import:
Spring Core: org.springframework.core.NestedExceptionUtils.getRootCause
Jackson: com.fasterxml.jackson.databind.util.ClassUtil.getRootCause
Guava (Swagger transitive) com.google.common.base.Throwables.getRootCause
Most smart (with cycle check) is Spring NestedExceptionUtils.getRootCause.
But, if your excetion has no cause, method returns null.
In my case it is wrong, so I've done:
#NonNull
public static Throwable getRootCause(#NonNull Throwable t) {
Throwable rootCause = NestedExceptionUtils.getRootCause(t);
return rootCause != null ? rootCause : t;
}
ExceptionUtils.getRootCause(), and Throwables.getRootCause() returns null if the cause of the exception being passed is null.The following method will return the original throwable if an throwable without a cause is being passed as the input parameter.
/**
* #return the root cause of a given throwable.
* If throwable without a cause is being passed, the original throwable will be returned
*/
public static Throwable getRootCause(#NonNull final Throwable throwable) {
List<Throwable> throwableList = ExceptionUtils.getThrowableList(throwable);
return throwableList.get(throwableList.size() - 1);
}
One line solution using core Java API:
try {
i = 1 / 0;
} catch (ArithmeticException e) {
System.out.println(new ArithmeticException().initCause(e).getCause());
}
One more solution below works as well:
try {
i = 1 / 0;
} catch (ArithmeticException e) {
System.out.println(new Exception().initCause(e).getCause());
}
Both of them will print
java.lang.ArithmeticException: / by zero
I want to add Kotlin extension functions to get root causes:
fun Throwable.rootCause(): Throwable {
return if (cause == null) this else cause!!.rootCause()
}
//Return null if first cause is null
fun Throwable.optRootCause(): Throwable? {
return if (cause == null) null else cause!!.rootCause()
}
Or this one if need to find a cause inside the throwable chain at any points:
fun <T : Throwable> Throwable.isOrContainsCauseOfType(clazz: KClass<T>): Throwable? {
return when {
clazz.isInstance(this) -> this //remove if you want to exclude [this]
cause == null -> null
clazz.isInstance(cause) -> cause
else -> cause!!.isOrContainsCauseOfType(clazz)
}
}
If the exception being thrown is always going to be of a specific type, like OracleException, you can catch just that exception.
For example:
try {
...
} catch(OracleException oe) {
...
}
This would only apply if there are specific Oracle exceptions being thrown. I don't know much about Oracle, so before attempting this you will probably want to find out if that's what's happening.
on 28-01-2015 , i have unable to solve my problem with any of the above solution, so my recommendation is to use :
e.getMessage().toString();
Ps: i am using it on android.